Я создал приложение для обмена сообщениями с поддельным всплывающим окном (обычное занятие с прозрачным фоном), которое отображает любые полученные 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%"
Большое спасибо за вашу помощь заранее:)