Android - Управление анимацией видоискателя пальцем / касанием? - PullRequest
4 голосов
/ 27 июля 2011

Я создал приложение для обмена сообщениями с поддельным всплывающим окном (обычное занятие с прозрачным фоном), которое отображает любые полученные SMS-сообщения, и вы можете «пролистывать» между любыми полученными текстами (переключать представления) пальцем влево / вправо (для перехода к предыдущему / следующему), но в идеале я хочу управлять анимацией движением пальца пользователя, чтобы (например), если пользователь касается экрана и перемещает палец влево, вид будет переворачиваться / анимироваться относительно как насколько палец пользователя сдвинулся. Кроме того, если анимация достигает середины и пользователь поднимает палец с экрана, анимация просто завершится и покажет следующий вид, и, как я видел в других приложениях, если она не достигла середины анимации, просто вернется в исходное положение.

В флиппере представления есть 2 идентичных вида (тот, который не отображается, загружает следующий / предыдущий текст в зависимости от направления движения пальца пользователя). Вот XML для макета:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:padding="20dp"
          >
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/outermost_layout"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:background="#364395"
          >
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/navbutton_layout"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:gravity="center"
          android:layout_height="wrap_content"
          android:background="#364395"
          android:padding="10dp"
          >     
          <TextView android:text="" 
          android:id="@+id/previous_sms" 
          android:layout_width="100px" 
          android:layout_height="30px"
          android:background="#5E69AA"/>
          <TextView android:text="TextView" 
          android:id="@+id/sms_count" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content"/>
          <TextView android:text="" 
          android:id="@+id/next_sms" 
          android:layout_width="100px" 
          android:layout_height="30px"
          android:background="#5E69AA"/>

                </LinearLayout>
          <ViewFlipper
           android:id="@+id/viewflipper"
           android:layout_width="fill_parent"
           android:layout_height="fill_parent">
            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/outer_layout"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:background="#364395"
          android:padding="10dp"
          android:gravity="center"
          >
            <TextView android:text="TextView" 
                      android:id="@+id/smspopup_title"
                      android:textColor="#FFF" 
                      android:layout_width="wrap_content" 
                      android:layout_height="55dp"
                      android:textSize="24dp"
                      />
              <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/body_layout"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="150px"
              android:padding="10dp">
              <ScrollView android:id="@+id/scrollView1" 
                          android:layout_height="match_parent" 
                          android:layout_width="match_parent">
                        <TextView android:text="TextView" 
                                  android:id="@+id/smspopup_body" 
                                  android:textColor="#FFF"
                                  android:layout_width="wrap_content" 
                                  android:layout_height="wrap_content"
                                  android:textSize="18dp"
                                  />
              </ScrollView>
              </LinearLayout>
                      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                      android:id="@+id/button_layout"
                      android:orientation="horizontal"
                      android:layout_width="fill_parent"
                      android:layout_height="fill_parent"
                      android:gravity="center"                    
                      >
                        <Button android:text="Reply" 
                                android:id="@+id/reply_button" 
                                android:layout_width="wrap_content" 
                                android:layout_height="wrap_content" 
                                android:onClick="replyButtonHandler"
                                />
                        <Button android:text="Close" 
                                android:id="@+id/close_button" 
                                android:layout_width="wrap_content" 
                                android:layout_height="wrap_content" 
                                android:onClick="closeButtonHandler"
                                />
                    </LinearLayout>
        </LinearLayout>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/outer_layout2"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:background="#364395"
          android:padding="10dp"
          >
            <TextView android:text="TextView" 
                      android:id="@+id/smspopup_title2"
                      android:textColor="#FFF" 
                      android:layout_width="wrap_content" 
                      android:layout_height="55dp"
                      android:textSize="24dp"
                      />
              <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/body_layout2"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="150px"
              android:padding="10dp">
              <ScrollView android:id="@+id/scrollView2" 
                          android:layout_height="match_parent" 
                          android:layout_width="match_parent">
                        <TextView android:text="TextView" 
                                  android:id="@+id/smspopup_body2" 
                                  android:textColor="#FFF"
                                  android:layout_width="wrap_content" 
                                  android:layout_height="wrap_content"
                                  android:textSize="18dp"
                                  />
              </ScrollView>
              </LinearLayout>
                      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                      android:id="@+id/button_layout2"
                      android:orientation="horizontal"
                      android:layout_width="fill_parent"
                      android:layout_height="fill_parent"
                      android:gravity="center"                    
                      >
                        <Button android:text="Reply" 
                                android:id="@+id/reply_button2" 
                                android:layout_width="wrap_content" 
                                android:layout_height="wrap_content" 
                                android:onClick="replyButtonHandler"
                                />
                        <Button android:text="Close" 
                                android:id="@+id/close_button2" 
                                android:layout_width="wrap_content" 
                                android:layout_height="wrap_content" 
                                android:onClick="closeButtonHandler"
                                />
                    </LinearLayout>
        </LinearLayout>
        </ViewFlipper>
        </LinearLayout>

А вот фрагмент кода для переключения между представлениями:

public class SMSPopup extends Activity {
private NotificationManager mManager;



private static final int APP_ID = 0;
ViewFlipper viewFlipper;
 Animation animFlipInNext;
 Animation animFlipOutNext; 
 Animation animFlipInPrevious;
 Animation animFlipOutPrevious;
 boolean flipped = false;
String number ="";
String message = "";
Notification notification;
int messageCount = 0;
TextView messageCountDisplay;
TextView title;
TextView title2;
TextView bodyText;
TextView bodyText2;
TextView nextsms;
TextView prevsms;
int currentDisplayedSMS =0;
ArrayList<ArrayList<String>> arrayOfSMS ;
private float oldTouchValue;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.sms_popup);


    //2d array to hold our messages
    arrayOfSMS = new ArrayList<ArrayList<String>>();

    //viewflipper to switch between messages
    viewFlipper = (ViewFlipper)findViewById(R.id.viewflipper);
    //animations of switching between views
    animFlipInNext = AnimationUtils.loadAnimation(this, R.anim.flipinnext);
    animFlipOutNext = AnimationUtils.loadAnimation(this, R.anim.flipoutnext);
    animFlipInPrevious = AnimationUtils.loadAnimation(this, R.anim.flipinprevious);
    animFlipOutPrevious = AnimationUtils.loadAnimation(this, R.anim.flipoutprevious);

    //retrieve message
    Bundle extras = getIntent().getExtras();
    if(extras !=null)
    {
        number = extras.getString("number");
        message = extras.getString("message");
        //add to our array
        ArrayList<String> smsMessage = new ArrayList<String>();
        smsMessage.add(number);
        smsMessage.add(message);
        arrayOfSMS.add(smsMessage);
        currentDisplayedSMS = arrayOfSMS.indexOf(smsMessage);
        //set message count
        messageCount++;
        messageCountDisplay = (TextView) this.findViewById(R.id.sms_count);
        messageCountDisplay.setText("1/"+messageCount);
    }


    //set message into the textviews
   title = (TextView) this.findViewById(R.id.smspopup_title);
   title.setText("Message from "+fetchNameFromNumber(number));
   bodyText = (TextView) this.findViewById(R.id.smspopup_body);
   bodyText.setText(message);

   title2 = (TextView) findViewById(R.id.smspopup_title2);
   bodyText2 = (TextView) this.findViewById(R.id.smspopup_body2);
}

protected void onNewIntent(Intent intent)
{
    super.onNewIntent(intent);

    Bundle extras = intent.getExtras();
    if(extras !=null)
    {
        number = extras.getString("number");
        message = extras.getString("message");
        messageCount++;
        messageCountDisplay.setText("1/"+messageCount);
        //add to our array
        ArrayList<String> smsMessage = new ArrayList<String>();
        smsMessage.add(number);
        smsMessage.add(message);
        arrayOfSMS.add(smsMessage);
    }


}



public void setNextView()
{
    if(viewFlipper.getCurrentView().equals((View)findViewById(R.id.outer_layout)))
    {
        if(currentDisplayedSMS<messageCount)
        {
            currentDisplayedSMS++;
            if(currentDisplayedSMS>=messageCount)
            currentDisplayedSMS=messageCount-1; 
        }
        ArrayList<String> smsMessage = arrayOfSMS.get(currentDisplayedSMS);
        messageCountDisplay.setText((currentDisplayedSMS+1)+"/"+messageCount);
        title2.setText("Message from "+smsMessage.get(0));
           bodyText2.setText(smsMessage.get(1));  
    }
    else if(viewFlipper.getCurrentView().equals((View)findViewById(R.id.outer_layout2)))
    {
        if(currentDisplayedSMS<messageCount)
        {
            currentDisplayedSMS++;
            if(currentDisplayedSMS>=messageCount)
            currentDisplayedSMS=messageCount-1; 
        }
        ArrayList<String> smsMessage = arrayOfSMS.get(currentDisplayedSMS);
        messageCountDisplay.setText((currentDisplayedSMS+1)+"/"+messageCount);
        title.setText("Message from "+smsMessage.get(0));
           bodyText.setText(smsMessage.get(1));  
    }
}
public void setPreviousView()
{
    if(viewFlipper.getCurrentView().equals((View)findViewById(R.id.outer_layout)))
    {
        if(currentDisplayedSMS>0)
        {
            currentDisplayedSMS--;
            if(currentDisplayedSMS<=0)
            currentDisplayedSMS=0;  
        }
        ArrayList<String> smsMessage = arrayOfSMS.get(currentDisplayedSMS);
        messageCountDisplay.setText((currentDisplayedSMS+1)+"/"+messageCount);
        title2.setText("Message from "+smsMessage.get(0));
           bodyText2.setText(smsMessage.get(1));  
    }
    else if(viewFlipper.getCurrentView().equals((View)findViewById(R.id.outer_layout2)))
    {
        if(currentDisplayedSMS>0)
        {
            currentDisplayedSMS--;
            if(currentDisplayedSMS<=0)
            currentDisplayedSMS=0;  
        }
        ArrayList<String> smsMessage = arrayOfSMS.get(currentDisplayedSMS);
        messageCountDisplay.setText((currentDisplayedSMS+1)+"/"+messageCount);
        title.setText("Message from "+smsMessage.get(0));
           bodyText.setText(smsMessage.get(1));  
    }
}
public void removeCurrentSMS()
{
    ArrayList<String> smsMessage = arrayOfSMS.get(currentDisplayedSMS);        
    arrayOfSMS.remove(currentDisplayedSMS);
    //amend the current sms displayed 
    messageCount--;
    if(currentDisplayedSMS>0)
    {
        currentDisplayedSMS--;
    }
    else
    {
        currentDisplayedSMS= 0;
    }
    //get the new current message
    smsMessage = arrayOfSMS.get(currentDisplayedSMS);
    //amend the message count display
    messageCountDisplay.setText((currentDisplayedSMS+1)+"/"+messageCount);
    //amend the current view
    if(viewFlipper.getCurrentView().equals((View)findViewById(R.id.outer_layout)))
    {
        title.setText("Message from "+smsMessage.get(0));
        bodyText.setText(smsMessage.get(1));          
    }
    else if(viewFlipper.getCurrentView().equals((View)findViewById(R.id.outer_layout2)))
    {
        title2.setText("Message from "+smsMessage.get(0));
        bodyText2.setText(smsMessage.get(1));
    }
    messageCountDisplay.setText((currentDisplayedSMS+1)+"/"+messageCount);

}
public void replyButtonHandler(View v)
{
    ArrayList<String> smsMessage = arrayOfSMS.get(currentDisplayedSMS);
    Intent sendIntent;

    sendIntent = new Intent(Intent.ACTION_VIEW);         
        sendIntent.setData(Uri.parse("sms:"+smsMessage.get(0)));

    if(arrayOfSMS.size()==1)
    {
        finish();
    }
    else
    removeCurrentSMS();
  //sendIntent.putExtra("sms_body", "this is the body text"); 
    startActivity(sendIntent);
}
public void closeButtonHandler(View v)
{
    if(messageCount>1)
    removeCurrentSMS();
    else
    finish();
}

 @Override
    public boolean onTouchEvent(MotionEvent touchevent) {
     if(arrayOfSMS.size()<=1)
     {
         /*Toast.makeText(getBaseContext(), 
                 "Array too small - no sms to switch to", 
                 Toast.LENGTH_SHORT).show();*/
         return false;
     }
        switch (touchevent.getAction())
        {
            case MotionEvent.ACTION_DOWN:
            {
                oldTouchValue = touchevent.getX();
                break;
            }
            case MotionEvent.ACTION_UP:
            {
                float currentX = touchevent.getX();
                if (oldTouchValue < currentX)
                {
                    viewFlipper.setInAnimation(animFlipInNext);
                    viewFlipper.setOutAnimation(animFlipOutNext);
                    if(currentDisplayedSMS>0)
                    {
                        setPreviousView();
                      viewFlipper.showNext();
                    }
                }
                if (oldTouchValue > currentX)
                {
                    viewFlipper.setInAnimation(animFlipInPrevious);
                    viewFlipper.setOutAnimation(animFlipOutPrevious);
                    if(currentDisplayedSMS<messageCount-1)
                    {
                          setNextView();
                          viewFlipper.showPrevious();
                    }
                }

            break;
            }
        }
        return false;
    }


}

Моя анимация довольно проста - fliinnext.xml =

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator">
<translate
 android:fromXDelta="-100%"
  android:toXDelta="0%"
 android:duration="500" />
</set>

flipoutnext.xml =

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator">
<translate
 android:fromXDelta="0%"
 android:toXDelta="100%"
 android:duration="500" />
</set>

flipinprevious аналогично flipinnext, но с android: fromXDelta = "100%", а flipoutprevious точно так же, как flipoutnext, но с android: toXDelta = "- 100%"

Большое спасибо за вашу помощь заранее:)

...