使用HorizontalScrollView实现侧滑ListView

来源:互联网 发布:windows安装python3 编辑:程序博客网 时间:2024/06/16 04:44

1.需求

1.1实现一个类似QQ的ListView侧滑菜单,

分析一下都有哪些要求:

  1. 可以侧滑拉出菜单
  2. 点击时如果不是点击已经打开的item需关闭之前的item
  3. 点击时如果是已经打开的item,则可以继续拉动

这里写图片描述

2.实现

2.1先继承HorizontalScrollView实现一个类,便于布局

package com.example.scrolllistview;import android.content.Context;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.MotionEvent;import android.view.WindowManager;import android.widget.Button;import android.widget.HorizontalScrollView;import android.widget.LinearLayout;import android.widget.TextView;public class ScrollListView extends HorizontalScrollView{    //记录各个宽度    private int wScreen;    private int wButton;    private boolean once;    private Button leftbtn;    private Button rightbtn;    private TextView tx;    //构造方法    public ScrollListView(Context context) {        super(context,null);    }    public ScrollListView(Context context ,AttributeSet set)    {        super(context,set,0);    }    public ScrollListView(Context context ,AttributeSet set ,int defStyle) {        super(context,set,defStyle);    }    //重载测量方法    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        if(!once)        {            //获得第一个布局            LinearLayout linearlayout = (LinearLayout)getChildAt(0);            leftbtn = (Button)linearlayout.getChildAt(0);            tx = (TextView)linearlayout.getChildAt(1);            rightbtn = (Button)linearlayout.getChildAt(2);            //获得屏幕的宽度            WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);            //Onmeasure方法会被多次使用,造成频繁的创建销毁对象,为了ui的性能建议不要这样使用            DisplayMetrics outMetrics = new DisplayMetrics();            wm.getDefaultDisplay().getMetrics(outMetrics);            wScreen = outMetrics.widthPixels;            wButton = wScreen/2;            //设置个子控件的宽度            leftbtn.getLayoutParams().width = wButton;            tx.getLayoutParams().width = wScreen;            rightbtn.getLayoutParams().width = wButton;            this.getParent();        }        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    //重载布局    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        //如果改变        if(changed)        {            //将view滑动到(x,y)处 坐标原点parentview 左上角            this.scrollTo(wButton, 0);            once = true;        }    }    @Override    public boolean performClick() {        return super.performClick();    }    public void close()    {        this.scrollTo(wButton, 0);    }    public void open()    {        this.scrollTo(wButton+wScreen, 0);    }}

2.2编写listview的item布局

<com.example.scrolllistview.ScrollListView     xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="80sp">    <LinearLayout         android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="match_parent">        <Button            android:id="@+id/leftbtn"            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:background="#303F9F"            android:text="@string/leftbtn"/>        <TextView            android:id="@+id/context"            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:text="@string/context"/>                <Button            android:id="@+id/rightbtn"            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:background="#303F9F"            android:text="@string/rightbtn"/>    </LinearLayout></com.example.scrolllistview.ScrollListView>

2.3编写适配器类

package com.example.scrolllistview;import java.util.List;import android.content.Context;import android.graphics.Color;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnTouchListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ListView;import android.widget.TextView;public class ModelAdapter extends BaseAdapter{    private boolean isMove;    private int oldItem = -1;    private ListView list;    private boolean closed = true;    private Context tx;    private int resourceID;    private List<Model> mlist;    public ModelAdapter(Context tx, int resourceid ,List<Model> list ,ListView listview) {        // TODO Auto-generated constructor stub        this.tx = tx;        this.resourceID = resourceid;        this.mlist = list;        this.list = listview;    }    @Override    public int getCount() {        return mlist.size();    }    @Override    public Object getItem(int position) {        return mlist.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(final int position, View convertView, ViewGroup parent) {        ViewHolder vh = null;        Model m = (Model)getItem(position);        if(convertView == null)        {            convertView = LayoutInflater.from(tx).inflate(this.resourceID, parent,false);            vh = new ViewHolder();            vh.leftbtn = (Button)convertView.findViewById(R.id.leftbtn);            vh.context = (TextView)convertView.findViewById(R.id.context);            vh.rightbtn = (Button)convertView.findViewById(R.id.rightbtn);            convertView.setTag(vh);        }        else        {            vh = (ViewHolder)convertView.getTag();        }        vh.leftbtn.setText(m.getLeftText());        vh.rightbtn.setText(m.getRigthText());        vh.context.setText(m.getContext());        //告知点击事件点击的是哪一个item        vh.context.setTag(position);        //点击事件        convertView.setOnTouchListener(new OnTouchListener() {            float oldX = 0;            int f = 0;            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    oldX = event.getX();                    ViewHolder viewHolder = new ViewHolder();                    viewHolder = (ViewHolder) v.getTag();                    //获得点击的位置                    //如果是全部关闭的可以移动                    if(oldItem == (Integer)viewHolder.context.getTag() || closed)                    {                        isMove = true;                        oldItem = (Integer)viewHolder.context.getTag();                    }                    else                    {                        isMove = false;                    }                    break;                case MotionEvent.ACTION_MOVE:                    //获得当前屏幕内可见的第一个                    f = list.getFirstVisiblePosition();                    //获得点击得位置                    if(!isMove)                    {                        ((ScrollListView)list.getChildAt(oldItem-f)).close();                        closed = true;                        event.setAction(MotionEvent.ACTION_CANCEL);                    }                    else                        closed = false;                case MotionEvent.ACTION_UP:                    float newX = event.getX();                    if(oldX == newX)                    {                        ((ScrollListView)list.getChildAt(oldItem-f)).close();                        closed = true;                        event.setAction(MotionEvent.ACTION_CANCEL);                    }                default:                    break;                }                return false;            }        });        //按钮的单击事件        vh.rightbtn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //获得当前点击哪个item                v.setBackgroundColor(Color.RED);            }        });        return convertView;    }    class ViewHolder    {        public Button leftbtn;        public TextView context;        public Button rightbtn;    }}

2.4编写主页面的布局,就一个listview

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <ListView              android:id="@+id/lview"              android:layout_width="match_parent"              android:layout_height="match_parent"/></RelativeLayout>

2.5Activity

package com.example.scrolllistview;import android.os.Bundle;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.view.Menu;import android.widget.ListView;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ListView list = (ListView)findViewById(R.id.lview);        //准备数据        List<Model> mList = new ArrayList<Model>();        for(int i=0;i<10;i++)        {            Model m = new Model("leftbtn"+i,"context"+i,"rightbtn"+i);            mList.add(m);        }        //适配器        ModelAdapter adapter = new ModelAdapter(MainActivity.this, R.layout.slistitem, mList,list);        list.setAdapter(adapter);    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }}
不提倡这样写,应该使用handler为主线程投递message,让主线程只负责布局。
0 0
原创粉丝点击