自定义列表视图关闭屏幕位置

时间:2015-08-21 10:19:15

标签: android android-listview

我有一个自定义列表视图,其中包含具有向左或向右滑动功能的项目... 问题是当我在列表视图上滑动可见项目时,屏幕外项目也分别向左或向右滑动。如何防止屏幕外物品滑动?

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;
    }
}

1 个答案:

答案 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()'我确定我没有完全达到距离。但我已经测试了它并且它有效。

重点是:

  • 使用列表行时,使动画效果永久化是没有用的
  • 适配器维护列表项以显示基础数据。当数据发生变化时,请调用'notifyDatasetChanged()'并让适配器完成其工作。