#android #listview #swipe #onfling
#Android #listview #проведите пальцем #при запуске
Вопрос:
Я бы хотел, чтобы в моем приложении было такое же поведение, как в родном приложении contacts. В частности, я хотел бы реализовать свайп вправо для вызова и свайп влево для textmsg. У меня есть ListView, я настроил ArrayAdapter и реализовал детектор жестов для onFlingMethod. Я правильно перехватываю сторону пролистывания и могу запустить приложение вызова. Мне нужно указать номер элемента (и другую информацию) в Intent, поэтому мне нужно получить перемещенный элемент. Вот мой код.
public class Contacts extends Activity implements OnGestureListener {
private static final String TAG = "[Contacts]";
ArrayList < ContactInfo > mData;
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
/** Called when the activity is first created. */
private GestureDetector detector = new GestureDetector(this);
Button btnContacts;
Button btnProfile;
Button btnSettings;
ImageButton btnStatus;
HandleServer cubeServer;
Button slideHandleButton;
SlidingDrawer slidingDrawer;
String filter = "n";
ArrayAdapter < ContactInfo > adapter;
ListView listView;
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
return true;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contact);
listView = (ListView) findViewById(R.id.arrayList);
listView.setCacheColorHint(R.color.white);
mData = getContact();
adapter = new ArrayAdapter < ContactInfo > (this.getApplicationContext(), R.layout.row, R.id.nome, mData) {
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row, null);
viewHolder = new ViewHolder();
final ContactInfo item = getItem(position);
viewHolder.name.setText(item.getName());
convertView.setClickable(true);
OnClickListener myClickListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), ContactTabs.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//Log.i(TAG,"id value:" item.getId());
intent.putExtra("id", item.getId());
intent.putExtra("name", item.getName());
//aggiungi quello che serve per gli extra ed i task
intent.putExtra("calendar", item.getCalendarDraw());
intent.putExtra("gmail", item.getGmailDraw());
intent.putExtra("operator", item.getOperatorDraw());
intent.putExtra("imgStatus", item.getImgStatusDraw());
startActivity(intent);
}
};
convertView.setOnClickListener(myClickListener);
convertView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View view, MotionEvent e) {
detector.onTouchEvent(e);
return false;
}
});
return convertView;
}
};
listView.setAdapter(adapter);
}
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
return false;
}
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE amp;amp; Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//CallNativeApp cna = new CallNativeApp(getApplicationContext());
//cna.sendSms("11111", "");
Toast.makeText(getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE amp;amp; Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//CallNativeApp cna = new CallNativeApp(getApplicationContext());
//cna.call("1111");
Toast.makeText(getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// nothing
}
return true;
}
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return true;
}
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return true;
}
}
}
Комментарии:
1. с какой проблемой вы столкнулись здесь?? это работает так, как ожидалось?
Ответ №1:
Я решаю эту проблему с помощью ListView.pointToPosition()
метода.
Вот мой фрагмент кода:
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
if (e2.getX() - e1.getX() > MOVE) {
int id = list.pointToPosition((int) e1.getX(), (int) e1.getY());
Reminder temp = (Reminder) adapter.getItem((id));
return true;
}
return false;
}
Сначала вы получаете rowID из list.pointToPosition((int) e1.getX(), (int) e1.getY());
и делаете с ним все, что хотите. В моем случае напоминание — это тип объектов в моем пользовательском адаптере массива для списка.
Ответ №2:
Я бы предположил, что способ сделать это — добавить GestureListener в строку, как вы делаете с OnClickListener, вместо основного действия.
Если у вас большой список, это будет означать множество GestureListeners и может повлиять на производительность. В этом случае вам, возможно, было бы лучше вычислить, какой вид был просмотрен, используя положение прокрутки и представления.
Ответ №3:
Наконец, я получил решение получать индекс при пролистывании влево или вправо в режиме просмотра списка…. @Переопределить общедоступный логический запуск (MotionEvent e1, MotionEvent e2, float velocityX, float velocityyy) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD amp;amp; Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
int id = list.pointToPosition((int) e1.getX(), (int) e1.getY());
task = (TaskClass) adapter.getItem((id));
Log.e("Result", "Result..." task.toString());
onSwipeRight(task.milestonetask);
} else {
int id = list.pointToPosition((int) e1.getX(), (int) e1.getY());
task = (TaskClass) adapter.getItem((id));
onSwipeLeft(task.milestonetask);
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD amp;amp; Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom();
} else {
onSwipeTop();
}
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return resu<
}