zoukankan      html  css  js  c++  java
  • Android 用HorizontalScrollView实现ListView的Item滑动删除 ,滑动错乱 冲突

    测试于:Android2.2+

    对于Android来说按键操作已经在减少,越来越多的手势操作层出不穷,今天介绍一款LIstView的Item滑动删除的实现方式。

    原理:

    利用HorizontalScrollView可以横向滚动的特点实现滑动,根据动态的设置要展示的区域宽度,使得其余选项操作被挤出屏幕外面,从而实现单条滑动菜单的样式。

    实现步骤:

    1. 实现Listview的Item布局文件item_list.layout
      <?xml version="1.0" encoding="utf-8"?>
      <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/hsv"
          android:layout_width="wrap_content"
          android:layout_height="80dip"
          android:scrollbars="none" >
      
          <LinearLayout
              android:layout_width="wrap_content"
              android:layout_height="match_parent"
              android:orientation="horizontal" >
      
              <LinearLayout
                  android:id="@+id/ll_content"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" >
      
                  <TextView
                      android:id="@+id/tv"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:gravity="center"
                      android:text="" />
              </LinearLayout>
      
              <LinearLayout
                  android:id="@+id/ll_action"
                  android:layout_width="wrap_content"
                  android:layout_height="match_parent"
                  android:orientation="horizontal" >
      
                  <Button
                      android:id="@+id/button1"
                      android:layout_width="wrap_content"
                      android:layout_height="match_parent"
                      android:background="@android:color/darker_gray"
                      android:paddingLeft="20dip"
                      android:paddingRight="20dip"
                      android:text="@string/action1" />
      
                  <Button
                      android:id="@+id/button2"
                      android:layout_width="wrap_content"
                      android:layout_height="match_parent"
                      android:layout_marginLeft="2dip"
                      android:layout_marginRight="2dip"
                      android:background="@android:color/darker_gray"
                      android:paddingLeft="20dip"
                      android:paddingRight="20dip"
                      android:text="@string/action2" />
      
                  <Button
                      android:id="@+id/button3"
                      android:layout_width="wrap_content"
                      android:layout_height="match_parent"
                      android:background="@android:color/darker_gray"
                      android:paddingLeft="20dip"
                      android:paddingRight="20dip"
                      android:text="@string/action3" />
              </LinearLayout>
          </LinearLayout>
      
      </HorizontalScrollView>
    2. 准备MainActivity初始化Listview
      package com.yzy.horizontalscrollview;
      
      import android.app.Activity;
      import android.os.Bundle;
      import android.util.DisplayMetrics;
      import android.widget.ListView;
      import com.yzy.horizontalscrollview.R;
      
      public class MainActivity extends Activity {
      
          private ListView mListView;
      
          private MyAdapter mAdapter;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              mListView = (ListView) findViewById(R.id.listView);
              DisplayMetrics dm = new DisplayMetrics();
              getWindowManager().getDefaultDisplay().getMetrics(dm);
              mAdapter = new MyAdapter(this, dm.widthPixels);
              mListView.setAdapter(mAdapter);
          }
      }
    3. 继承BaseAdapter实现自定义的适配器MyAdapter
      package com.yzy.horizontalscrollview;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import android.content.Context;
      import android.view.LayoutInflater;
      import android.view.MotionEvent;
      import android.view.View;
      import android.view.ViewGroup;
      import android.view.ViewGroup.LayoutParams;
      import android.widget.BaseAdapter;
      import android.widget.Button;
      import android.widget.HorizontalScrollView;
      import android.widget.TextView;
      import com.yzy.horizontalscrollview.R;
      
      public class MyAdapter extends BaseAdapter implements View.OnClickListener {
          // 数据源,用于存放颜色值的。
          private List<Integer> colors;
          private Context mContext;
          // 屏幕宽度,由于我们用的是HorizontalScrollView,所以按钮选项应该在屏幕外
          private int mScreentWidth;
          private View view;
      
          /**
           * 构造方法
           * 
           * @param context
           * @param screenWidth
           */
          public MyAdapter(Context context, int screenWidth) {
      
              // 初始化
              mContext = context;
              mScreentWidth = screenWidth;
      
              // 填充list的内容模拟数据,否则应该异步执行
              colors = new ArrayList<Integer>();
              for (int i = 0; i < 15; i++) {
                  colors.add(R.color.blue);
              }
          }
      
          @Override
          public int getCount() {
              return colors.size();
          }
      
          @Override
          public Object getItem(int position) {
              return colors.get(position);
          }
      
          @Override
          public long getItemId(int position) {
              return position;
          }
      
          @Override
          public View getView(int position, View convertView, ViewGroup parent) {
              ViewHolder holder;
              // 如果没有设置过,初始化convertView
              if (convertView == null) {
                  // 获得设置的view
                  convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, parent, false);
      
                  // 初始化holder
                  holder = new ViewHolder();
                  holder.hSView = (HorizontalScrollView) convertView.findViewById(R.id.hsv);
      
                  holder.action = convertView.findViewById(R.id.ll_action);
                  holder.btOne = (Button) convertView.findViewById(R.id.button1);
                  holder.btTwo = (Button) convertView.findViewById(R.id.button2);
                  holder.btThree = (Button) convertView.findViewById(R.id.button3);
                  holder.tvContent = (TextView) convertView.findViewById(R.id.tv);
      
                  // 设置内容view的大小为屏幕宽度,这样按钮就正好被挤出屏幕外
                  holder.content = convertView.findViewById(R.id.ll_content);
                  LayoutParams lp = holder.content.getLayoutParams();
                  lp.width = mScreentWidth;
      
                  convertView.setTag(holder);
              } else {
                  // 有直接获得ViewHolder
                  holder = (ViewHolder) convertView.getTag();
              }
              // 把位置放到view中,这样点击事件就可以知道点击的是哪一条item
              holder.btOne.setTag(position);
              holder.btTwo.setTag(position);
              holder.btThree.setTag(position);
      
              // 设置监听事件
              convertView.setOnTouchListener(new View.OnTouchListener()
              {
                  @Override
                  public boolean onTouch(View v, MotionEvent event)
                  {
                      switch (event.getAction())
                      {
                          case MotionEvent.ACTION_DOWN:
                              if (view != null) {
                                  ViewHolder viewHolder1 = (ViewHolder) view.getTag();
                                  viewHolder1.hSView.smoothScrollTo(0, 0);
                              }
                          case MotionEvent.ACTION_UP:
                              // 获得ViewHolder
                              ViewHolder viewHolder = (ViewHolder) v.getTag();
                              view = v;
                              // 获得HorizontalScrollView滑动的水平方向值.
                              int scrollX = viewHolder.hSView.getScrollX();
      
                              // 获得操作区域的长度
                              int actionW = viewHolder.action.getWidth();
      
                              // 注意使用smoothScrollTo,这样效果看起来比较圆滑,不生硬
                              // 如果水平方向的移动值<操作区域的长度的一半,就复原
                              if (scrollX < actionW / 2)
                              {
                                  viewHolder.hSView.smoothScrollTo(0, 0);
                              }
                              else// 否则的话显示操作区域
                              {
                                  viewHolder.hSView.smoothScrollTo(actionW, 0);
                              }
                              return true;
                      }
                      return false;
                  }
              });
      
              // 这里防止删除一条item后,ListView处于操作状态,直接还原
              if (holder.hSView.getScrollX() != 0) {
                  holder.hSView.scrollTo(0, 0);
              }
      
              // 设置背景颜色,设置填充内容.
              holder.content.setBackgroundResource(colors.get(position));
              holder.tvContent.setText("" + position);
      
              // 设置监听事件
              holder.btOne.setOnClickListener(this);
              holder.btTwo.setOnClickListener(this);
              holder.btThree.setOnClickListener(this);
      
              return convertView;
          }
      
          /**
           * ViewHolder
           * 
           * @Title:
           * @Description:主要是避免了不断的view获取初始化.
           * @Author:yzy
           * @Since:2013-10-22
           */
          class ViewHolder {
              public HorizontalScrollView hSView;
      
              public View content;
              public TextView tvContent;
      
              public View action;
              public Button btOne;
              public Button btTwo;
              public Button btThree;
          }
      
          @Override
          public void onClick(View v) {
              int position = (Integer) v.getTag();
              switch (v.getId()) {
                  case R.id.button1:
                      colors.add(R.color.blue);
                      break;
                  case R.id.button2:
                      colors.remove(position);
                      break;
                  case R.id.button3:
                      if (colors.get(position) == R.color.blue) {
                          colors.set(position, R.color.red);
                      } else {
                          colors.set(position, R.color.blue);
                      }
                      break;
      
                  default:
                      break;
              }
              // 刷新ListView内容
              notifyDataSetChanged();
          }
      }

    效果图:

     Android ListView滑动删除用HorizontalScrollView实现

    还有很多的实现方式,希望大家多多指教哦,附件里面是源码本人测试通过的。

    下载:ListViewHorizontalScrollview.zip


    最近在开发中遇到HorizontalScrollView嵌套ScrollView导致滑动卡的情况,急横向水平滑动的View和垂直水平滑动的View,都在接收处理滑动时间,但是这种情况下触摸事件就会发生冲突。导致滑动非常卡,甚至出现程序停止响应。这种情况下我们需要重写view。下面是两个简单的例子,重写水平滑动View只接收水平方向上滑动的事件。我们使用手势GestureDetector来作区分

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.GestureDetector;
    import android.view.GestureDetector.SimpleOnGestureListener;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.HorizontalScrollView;
    
    public class CustomHScrollView extends HorizontalScrollView{
        private GestureDetector mGestureDetector;
        private View.OnTouchListener mGestureListener;
    
        private static final String TAG = "CustomHScrollView";
    
        /**
         * @function CustomHScrollView constructor
         * @param context Interface to global information about an application environment.
         *
         */
        public CustomHScrollView(Context context) {
            super(context);
    // TODO Auto-generated constructor stub
            mGestureDetector = new GestureDetector(new HScrollDetector());
            setFadingEdgeLength(0);
        }
    
        /**
         * @function CustomHScrollView constructor
         * @param context Interface to global information about an application environment.
         * @param attrs A collection of attributes, as found associated with a tag in an XML document.
         */
        public CustomHScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
    // TODO Auto-generated constructor stub
            mGestureDetector = new GestureDetector(new HScrollDetector());
            setFadingEdgeLength(0);
        }
    
        /**
         * @function CustomHScrollView constructor
         * @param context Interface to global information about an application environment.
         * @param attrs A collection of attributes, as found associated with a tag in an XML document.
         * @param defStyle style of view
         */
        public CustomHScrollView(Context context, AttributeSet attrs,
                                 int defStyle) {
            super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
            mGestureDetector = new GestureDetector(new HScrollDetector());
            setFadingEdgeLength(0);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev);
        }
    
        // Return false if we're scrolling in the y direction
        class HScrollDetector extends SimpleOnGestureListener {
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                if(Math.abs(distanceX) > Math.abs(distanceY)) {
                    return true;
                }
    
                return false;
            }
        }
    
    }

           
  • 相关阅读:
    jmeter(46) redis
    jmeter(45) tcp/ip协议
    Codeforces Round #538 (Div. 2)D(区间DP,思维)
    Codeforces Global Round 1D(DP,思维)
    Educational Codeforces Round 57D(DP,思维)
    UPC11073(DP,思维)
    Yahoo Progamming Contest 2019D(DP,思维)
    Atcoder Beginner Contest 118D(DP,完全背包,贪心)
    Xuzhou Winter Camp 1C(模拟)
    Educational Codeforces Round 57 (Rated for Div. 2)D(动态规划)
  • 原文地址:https://www.cnblogs.com/sharecenter/p/5620975.html
Copyright © 2011-2022 走看看