kevin . zhang 2016-05-08 15:41 采纳率: 50%
浏览 1488

HorizontalScrollView在ListView被回收利用

我有一个ListView,子view是HorizontalScrollView,当我对的ListView中的第一个子HorizontalScrollView从右边滑动到左边,把删除按钮显示出来之后,我再操作ListView上下滚动时,ListView会复用之前滑动HorizontalScrollView的view.

图片说明

图片说明

我的代码:
ListView 子view布局:

 <?xml version="1.0" encoding="utf-8"?>
<com.example.administrator.myapplication.DeleteView
    android:id="@+id/GrafDelete_root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#f1f1f1"
    android:scrollbars="none"
    >

    <LinearLayout
        android:id="@+id/ll_content"
        android:layout_width="920px"
        android:layout_height="180px"
        android:orientation="horizontal">

        <RelativeLayout
            android:id="@+id/re_select"
            android:layout_width="80px"
            android:layout_height="180px"
            android:background="@color/colorAccent">

            <ImageView
                android:id="@+id/select"
                android:layout_width="36px"
                android:layout_height="36px"
                android:layout_centerInParent="true"
                android:scaleType="centerCrop"/>
        </RelativeLayout>

        <AbsoluteLayout
            android:id="@+id/ab_view_bg"
            android:layout_width="720px"
            android:layout_height="180px">

            <TextView
                android:id="@+id/text_title"
                android:layout_width="450px"
                android:layout_height="80px"
                android:layout_x="20px"
                android:layout_y="30px"
                android:gravity="center_vertical"
                android:maxLines="2"
                android:textColor="#515151"
                android:textSize="30px"
                />
        </AbsoluteLayout>

        <AbsoluteLayout
            android:id="@+id/ab_delete_bg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <View
                android:id="@+id/view_delete_bg"
                android:layout_width="120px"
                android:layout_height="180px"
                android:background="#ff0000"
                ></View>

            <TextView
                android:id="@+id/text_delete"
                android:layout_width="120px"
                android:layout_height="60px"
                android:layout_y="90px"
                android:gravity="center"
                android:text="删除"
                android:textColor="#ffffff"
                android:textSize="30px"
                />
        </AbsoluteLayout>
    </LinearLayout>
</com.example.administrator.myapplication.DeleteView>

自定义的HorizontalScrollView,可以从又滑动到左边,显示被影藏的删除按钮:

 public class DeleteView extends HorizontalScrollView {
    private static final int SWIPE_MIN_DISTANCE = 5;
    private static final int SWIPE_THRESHOLD_VELOCITY = 600;
    private GestureDetector gestureDetector;

    private Context context;
    private int start;//开始滑动的位置
    private int end;//结束滑动的位置
    private VelocityTracker velocityTracker;
    private int width;//屏幕宽度的额外宽度。
    private boolean isEnableScroll;//是否打开水平滑动  true可以水平滑动  false不能水平滑动

    public DeleteView(Context context) {
        super(context);
    }

    public DeleteView(Context context, AttributeSet attrs) {
        super(context, attrs);
        width = 120;//设定额外的宽度
        gestureDetector = new GestureDetector(new MyGestureDetector());
    }

    public DeleteView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (velocityTracker == null) {
            velocityTracker = VelocityTracker.obtain();
        }
        if (!isEnableScroll)
            return true;
        if (gestureDetector.onTouchEvent(event))
            return true;

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            start = (int) event.getRawX();
        }
        if (event.getAction() == MotionEvent.ACTION_UP) {
            end = (int) event.getRawX();
            if (start > end) {
                if (getScrollX() < width / 2 || velocityTracker.getXVelocity() > SWIPE_THRESHOLD_VELOCITY) {
                    smoothScrollTo(0, 0);
                } else {
                    smoothScrollTo(width, 0);
                }
            }
            if (start < end) {
                if (getScrollX() > width / 2 || velocityTracker.getXVelocity() > SWIPE_THRESHOLD_VELOCITY) {
                    smoothScrollTo(width, 0);
                } else {
                    smoothScrollTo(0, 0);
                }
            }
            velocityTracker.clear();
            return true;
        }
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            velocityTracker.addMovement(event);
        }
        return super.onTouchEvent(event);
    }

    class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (!isEnableScroll)
                return true;
            try {
                //right to left
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    smoothScrollTo(width, 0);
                    return true;
                }
            } catch (Exception e) {
                // nothing
            }
            return false;
        }
    }

    //是否开启水平滑动
    public void setEnAbleHorizontalScroll(boolean b) {
        if (b == isEnableScroll) {
            return;
        } else {
            isEnableScroll = b;
        }
        if (!isEnableScroll) {
            smoothScrollTo(0, 0);
        }
    }
}

Adapter:

 public class ListAdapter extends BaseAdapter {
    private Context context;
    private ArrayList<ListItem> items;
    private boolean isAble;

    public ListAdapter(Context context, ArrayList<ListItem> items) {
        this.context = context;
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public ListItem getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
            holder.mDelete_Item_root = (DeleteView) convertView.findViewById(R.id.GrafDelete_root);
            holder.ll_content = (LinearLayout) convertView.findViewById(R.id.ll_content);
            holder.re_select = (RelativeLayout) convertView.findViewById(R.id.re_select);
            holder.select = (ImageView) convertView.findViewById(R.id.select);
            holder.ab_view_bg = (AbsoluteLayout) convertView.findViewById(R.id.ab_view_bg);
            holder.text_title = (TextView) convertView.findViewById(R.id.text_title);
            AbsoluteLayout ab_delete_bg = (AbsoluteLayout) convertView.findViewById(R.id.ab_delete_bg);
            holder.view_delete_bg = convertView.findViewById(R.id.view_delete_bg);
            TextView text_delete = (TextView) convertView.findViewById(R.id.text_delete);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if (isAble) {//Open edit
            DeleteView.LayoutParams layoutParams = new DeleteView.LayoutParams(920, 180);
            layoutParams.leftMargin = 0;
            holder.ll_content.setLayoutParams(layoutParams);
            ((DeleteView) convertView).setEnAbleHorizontalScroll(false);
        } else {//Editing is not open
            DeleteView.LayoutParams layoutParams = new DeleteView.LayoutParams(920, 180);
            layoutParams.leftMargin = -80;
            holder.ll_content.setLayoutParams(layoutParams);
            ((DeleteView) convertView).setEnAbleHorizontalScroll(true);
        }

        if (items.get(position).isSelected) {
            holder.select.setBackgroundResource(R.mipmap.item_selected1);
        } else {
            holder.select.setBackgroundResource(R.mipmap.item_select_un);
        }
        View.OnTouchListener listener = new View.OnTouchListener() {
            boolean select_out, delete_out;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        switch (v.getId()) {
                            case R.id.re_select:
                                select_out = false;
                                break;
                            case R.id.view_delete_bg:
                                holder.view_delete_bg.setAlpha(0.5f);
                                delete_out = false;
                                break;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        switch (v.getId()) {
                            case R.id.re_select:
                                int x = (int) event.getX();
                                int y = (int) event.getY();
                                if (x < 0 || y < 0 || x > holder.re_select.getWidth() || y > holder.re_select.getHeight()) {
                                    select_out = true;
                                }
                                break;
                            case R.id.view_delete_bg:
                                int x2 = (int) event.getX();
                                int y2 = (int) event.getY();
                                if (x2 < 0 || y2 < 0 || x2 > holder.view_delete_bg.getWidth() || y2 > holder.view_delete_bg.getHeight()) {
                                    holder.view_delete_bg.setAlpha(1.0f);
                                    delete_out = true;
                                }
                                break;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        switch (v.getId()) {
                            case R.id.re_select:
                                if (select_out) {
                                    return true;
                                }
                                if (items.get(position).isSelected) {
                                    items.get(position).isSelected = false;
                                    holder.select.setBackgroundResource(R.mipmap.item_select_un);
                                } else {
                                    items.get(position).isSelected = true;
                                    holder.select.setBackgroundResource(R.mipmap.item_selected1);
                                }
                                break;
                            case R.id.view_delete_bg:
                                holder.view_delete_bg.setAlpha(1.0f);
                                if (delete_out)
                                    return true;
                                if (isAble)
                                    return true;

                                break;
                        }
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        switch (v.getId()) {
                            case R.id.re_select:
                                break;
                            case R.id.view_delete_bg:
                                holder.view_delete_bg.setAlpha(1.0f);
                                break;
                        }
                        break;
                }
                return true;
            }
        };
        holder.re_select.setOnTouchListener(listener);
        holder.view_delete_bg.setOnTouchListener(listener);
        holder.text_title.setText(items.get(position).mString);
        return convertView;
    }

    private class ViewHolder {
        TextView text_title;
        RelativeLayout re_select;
        ImageView select;
        AbsoluteLayout ab_view_bg, ab_delete_bg;
        View view_delete_bg;
        //        TextView text_delete;
        LinearLayout ll_content;
        DeleteView mDelete_Item_root;
    }

    /**
     * You can edit
     */
    public void setIsAble(boolean b) {
        if (b == isAble) {
            return;
        } else {
            isAble = b;
            notifyDataSetChanged();
        }

    }
}

Activity:

 public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private TextView tv_button;
    private ArrayList<ListItem> mArrayList = new ArrayList<>();
    private boolean isAble;
    private ListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listView);
        tv_button = (TextView) findViewById(R.id.tv_button);

        getListItem();
        adapter = new ListAdapter(this, mArrayList);
        listView.setAdapter(adapter);

        setListener();
    }

    public void setListener() {
        View.OnTouchListener listener = new View.OnTouchListener() {
            boolean delete_out;

            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                switch (arg1.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        switch (arg0.getId()) {
                            case R.id.tv_button:
                                tv_button.setAlpha(0.5f);
                                delete_out = false;
                                break;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        switch (arg0.getId()) {
                            case R.id.tv_button:
                                int x2 = (int) arg1.getX();
                                int y2 = (int) arg1.getY();
                                if (x2 < 0 || y2 < 0 || x2 > tv_button.getWidth() || y2 > tv_button.getHeight()) {
                                    tv_button.setAlpha(1.0f);
                                    delete_out = true;
                                }
                                break;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        switch (arg0.getId()) {
                            case R.id.tv_button:
                                tv_button.setAlpha(1.0f);
                                if (delete_out)
                                    return true;
                                changeState();
                                break;
                        }
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        switch (arg0.getId()) {
                            case R.id.tv_button:
                                tv_button.setAlpha(1.0f);
                                break;
                        }
                }
                return true;
            }
        };
        tv_button.setOnTouchListener(listener);
    }
    //点编辑或完成时切换状态
    private void changeState() {
        if (isAble) {
            isAble = false;
            tv_button.setText("编辑");
        } else {
            isAble = true;
            tv_button.setText("完成");
        }
        adapter.setIsAble(isAble);
    }
    private void getListItem() {
        for (int i = 0; i < 20; i++) {
            ListItem listItem = new ListItem();
            listItem.mString = i + "\t" + "ScrollView and HorizontalScrollView conflict";

            mArrayList.add(listItem);
        }
    }
}
  • 写回答

8条回答 默认 最新

  • l_vaule 2016-05-08 16:13
    关注

    你用了viewholder他当然会复用啦。。

    评论

报告相同问题?

悬赏问题

  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型