原理:
利用HorizontalScrollView可以横向滚动的特点实现滑动,根据动态的设置要展示的区域宽度,使得其余选项操作被挤出屏幕外面,从而实现单条滑动菜单的样式。
实现步骤:
实现Listview的Item布局文件item_list.layout
<?xml version="1.0" encoding="utf-8"?><HorizontalScrollView xmlns:android="/apk/res/android"android:id="@+id/hsv"android:layout_width="wrap_content"android:layout_height="80dip"android:scrollbars="none" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="horizontal" ><LinearLayoutandroid:id="@+id/ll_content"android:layout_width="match_parent"android:layout_height="match_parent" ><TextViewandroid:id="@+id/tv"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:text="" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_action"android:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="horizontal" ><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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>
准备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;@Overrideprotected 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);}}
继承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);}}@Overridepublic int getCount() {return colors.size();}@Overridepublic Object getItem(int position) {return colors.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;// 如果没有设置过,初始化convertViewif (convertView == null) {// 获得设置的viewconvertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, parent, false);// 初始化holderholder = 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 {// 有直接获得ViewHolderholder = (ViewHolder) convertView.getTag();}// 把位置放到view中,这样点击事件就可以知道点击的是哪一条itemholder.btOne.setTag(position);holder.btTwo.setTag(position);holder.btThree.setTag(position);// 设置监听事件convertView.setOnTouchListener(new View.OnTouchListener(){@Overridepublic 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:// 获得ViewHolderViewHolder 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:-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;}@Overridepublic 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();}}
效果图: