我有一个自定义列表视图,其中包含具有向左或向右滑动功能的项目... 问题是当我在列表视图上滑动可见项目时,屏幕外项目也分别向左或向右滑动。如何防止屏幕外物品滑动?
public class TestListViewAdapter extends BaseAdapter {
Context context;
ArrayList<RowItem> arrayList;
LayoutInflater layoutInflater;
public TestListViewAdapter(Context context,ArrayList<RowItem> arrayList,DataSource dataSource){
this.context = context;
this.arrayList =arrayList;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.txtTitle = (TextView)convertView.findViewById(R.id.handle_c);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.txtTitle.setText(arrayList.get(position).getTitle());
if(arrayList.get(position).getleft()) {
//txtTitle.setGravity(Gravity.RIGHT);
setMargins(holder.txtTitle, px2dp(55), 0, 0,0);
}else {
//txtTitle.setGravity(Gravity.RIGHT);
setMargins(holder.txtTitle, 0,0,px2dp(55),0);
}
convertView.setOnTouchListener(new OnSwipeTouchListener(context) {
@Override
public void onSwipeLeft(View view) {
if (arrayList.get(position).getleft()){
arrayList.get(position).setleft(false);
Animation animationtranslate_left = new TranslateAnimation(px2dp(55+arrayList.get(position).getPX()),px2dp(0+arrayList.get(position).getPX()),0,0);
animationtranslate_left.setDuration(100);
//animationtranslate.setFillAfter(true);
//Animation anim = AnimationUtils.loadAnimation(getContext(), R.anim.left_swipe);
try {
view.clearAnimation();
} catch (Exception e) {
}
if (view != null)
view.startAnimation(animationtranslate_left);
else
Log.e("View null", "Null");
animationtranslate_left.setFillAfter(true);
}
}
@Override
public void onSwipeRight(View view) {
if (!arrayList.get(position).getleft()) {
arrayList.get(position).setleft(true);
Animation animationtranslate_rigth = new TranslateAnimation(px2dp(0+arrayList.get(position).getPX()),px2dp(55+arrayList.get(position).getPX()),0 , 0);
animationtranslate_rigth. setDuration(100);
//animationtranslate.setFillAfter(true);
//Animation anim = AnimationUtils.loadAnimation(getContext(), R.anim.left_swipe);
try {
view.clearAnimation();
} catch (Exception e) {
}
if (view != null)
view.startAnimation(animationtranslate_rigth);
else
Log.e("View null", "Null");
animationtranslate_rigth.setFillAfter(true);
}
});
return convertView;
}
private class Detector extends GestureDetector {
View view;
public Detector(Context context, OnGestureListener listener) {
super(context, listener);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(ev);
}
public boolean onTouch(MotionEvent ev, View view) {
this.view = view.findViewById(R.id.handle_c);
return onTouchEvent(ev);
}
public View getView() {
return view;
}
private void setView(View view) {
this.view = view;
}
}
public class OnSwipeTouchListener implements View.OnTouchListener {
private final Detector gestureDetector;
public OnSwipeTouchListener(Context context) {
gestureDetector = (Detector) new Detector(context, new GestureListener());
}
public void onSwipeLeft(View view) {
}
public void onSwipeRight(View view) {
}
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouch(event, v);
}
private final class GestureListener extends Detector.SimpleOnGestureListener {
//private static final int SWIPE_MIN_DISTANCE = 20;
//private static final int SWIPE_MAX_OFF_PATH = 250;
//private static final int SWIPE_THRESHOLD_VELOCITY = 200;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
float ydis = e1.getY() - e2.getY();
if (ydis > 70) {
return super.onScroll(e1, e2, distanceX, distanceY);
} else {
if (e1.getX() - e2.getX() > 0) {
onSwipeLeft(gestureDetector.getView());
} else if (e1.getX() - e2.getX() < 0) {
onSwipeRight(gestureDetector.getView());
}
return false;
}
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
System.out.println("X1- " + e1.getX() + " X2- " + e2.getX() + " Y1- " + e1.getY() + " Y2- " + e2.getY());
if (e1.getX() - e2.getX() > 0) {
onSwipeLeft(gestureDetector.getView());
} else if (e1.getX() - e2.getX() < 0) {
onSwipeRight(gestureDetector.getView());
}
} catch (Exception e) {
Log.e("Home", "Error on gestures");
}
return false;
}
}
}
class ViewHolder{
TextView txtTitle;
}
public class RowItem {
private String title,id,name,number,primeri_id;
private boolean left;
private int px;
public boolean getleft(){return left;}
public int getPX(){return px;}
public void setleft(boolean b){left=b;}
public RowItem(boolean bl,String t,String id,String primeri_id){
title=t;
left=bl;
this.id = id;
this.primeri_id = primeri_id;
px=bl? -55:0;
}
public RowItem(String name ,String number){
this.name = name;
this.number= number;
}
public String getPrimeri_id() {
return primeri_id;
}
public void setPrimeri_id(String primeri_id) {
this.primeri_id = primeri_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
答案 0 :(得分:0)
似乎您的问题是由ListView行被回收的事实引起的。它们更像是个人数据出现在屏幕上时所戴的面具。所以你必须让他们独自一人,这意味着你写完每个动画后(同样的'......正确...'):
animationtranslate_left.setFillAfter(false);
为了实现文本位置的持续更改,我使用了一个简单的解决方法(也可以定义不同类型的行布局):
我将list_item.xml设为带有两个TextView的LinearLayout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/handle_c_left"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/handle_c_right"
/>
</LinearLayout>
同样改变了ViewHolder:
private static class ViewHolder
{
TextView txtTitle_1;
TextView txtTitle_2;
}
在'getView()'方法中,我添加了:
if(arrayList.get(position).getleft()) {
holder.txtTitle_1.setText(arrayList.get(position).getTitle());
holder.txtTitle_2.setVisibility(View.INVISIBLE);
holder.txtTitle_1.setVisibility(View.VISIBLE);
}else {
holder.txtTitle_2.setText(arrayList.get(position).getTitle());
holder.txtTitle_1.setVisibility(View.INVISIBLE);
holder.txtTitle_2.setVisibility(View.VISIBLE);
}
和我插入的每个'OnSwipe ...()'方法中的最后一个语句
notifyDataSetChanged();
由于更改了list_item.xml,因此还必须更改'gestureDetector.onTouch()'。我这样打补丁:
public boolean onTouch(MotionEvent ev, View view) {
//this.view = view.findViewById(R.id.handle_c);
this.view = view;
return onTouchEvent(ev);
}
在不知道所有代码的情况下,很难确定补丁是否正常,没有'px2dp()'我确定我没有完全达到距离。但我已经测试了它并且它有效。
重点是: