activity_main.xml
<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" tools:context="com.harvic.scrollview_scroller.MainActivity" > <com.harvic.scrollview_scroller.MyListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
item_layout.xml
<?xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lin_root" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:minHeight="120dp"> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FF83FA" android:gravity="center" android:textSize="25dp" /> <TextView android:id="@+id/del" android:layout_width="200dp" android:layout_height="fill_parent" android:background="#EEEEE0" android:text="删除" android:textSize="25dp" android:textColor="#ffffff" android:gravity="center" /> </LinearLayout>
MainActivity
package com.harvic.scrollview_scroller; import android.app.Activity; import android.os.Bundle; import android.view.View; import java.util.ArrayList; import java.util.List; import com.harvic.scrollview_scroller.MergeListAdapter.DataHolder; public class MainActivity extends Activity implements View.OnClickListener { private MyListView listView; private MergeListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (MyListView)findViewById(R.id.listview); final List<DataHolder> items = new ArrayList<DataHolder>(); for(int i=0;i<20;i++){ DataHolder item = new DataHolder(); item.title = "第"+i+"项"; items.add(item); } adapter = new MergeListAdapter(this,items,this); listView.setAdapter(adapter); } @Override public void onClick(View v) { if (v.getId() == R.id.del){ int position = listView.getPositionForView(v); adapter.removeItem(position); } } }
MergeListAdapter
package com.harvic.scrollview_scroller; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.TextView; import java.util.ArrayList; import java.util.List; /** * Created by enwei.zew on 2015/4/16. */ public class MergeListAdapter extends BaseAdapter { private Context mContext; private LayoutInflater mInflater; private List<DataHolder> mDataList = new ArrayList<DataHolder>(); private View.OnClickListener mDelClickListener; public MergeListAdapter(Context context, List<DataHolder> dataList, View.OnClickListener delClickListener) { mContext = context; mInflater = LayoutInflater.from(context); if (dataList != null && dataList.size() > 0) { mDataList.addAll(dataList); } mDelClickListener = delClickListener; } public void removeItem(int position) { mDataList.remove(position); notifyDataSetChanged(); } public void addItem(DataHolder item) { mDataList.add(item); notifyDataSetChanged(); } @Override public int getCount() { return mDataList.size(); } @Override public Object getItem(int position) { return mDataList.get(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.getTag() == null) { convertView = mInflater.inflate(R.layout.item_layout, parent, false); holder = new ViewHolder(); holder.title = (TextView) convertView.findViewById(R.id.title); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } DataHolder item = mDataList.get(position); holder.title.setText(item.title); item.rootView = (LinearLayout) convertView.findViewById(R.id.lin_root); item.rootView.scrollTo(0, 0); //点击删除实现方法二:交由外部处理: TextView delTv = (TextView) convertView.findViewById(R.id.del); delTv.setOnClickListener(mDelClickListener); return convertView; } private static class ViewHolder { public TextView title; } public static class DataHolder { public String title; public LinearLayout rootView; } }
MyListView
package com.harvic.scrollview_scroller; import com.harvic.scrollview_scroller.MergeListAdapter.DataHolder; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.animation.LinearInterpolator; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Scroller; public class MyListView extends ListView { // 每一个条目的容器控件 private LinearLayout itemRoot; // 上次手指的x轴坐标 private int mlastX = 0; // 删除控件的最大宽度 private final int MAX_WIDTH = 200; private Context mContext; // scrollTo()是没有办法加入运动的时间长度的,所以为了弥补这个问题,google就新增了一个类Scroller! private Scroller mScroller; public MyListView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; // 创建具有插值器的构造方法 mScroller = new Scroller(context, new LinearInterpolator(context, null)); } @Override public boolean onTouchEvent(MotionEvent event) { int maxLength = dipToPx(mContext, MAX_WIDTH); // 获取手势操作触发的xy轴坐标值 int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { // 我们想知道当前点击了哪一行 int position = pointToPosition(x, y); if (position != INVALID_POSITION) { // 获取点击的item控件的id值 DataHolder data = (DataHolder) getItemAtPosition(position); itemRoot = data.rootView; } } break; case MotionEvent.ACTION_MOVE: { // 获取item的容器控件在x轴偏移量 int scrollX = itemRoot.getScrollX(); // 实时获取最新的偏移量 int newScrollX = scrollX + mlastX - x; // 假设手势向右边滑动,可能<0 if (newScrollX < 0) { newScrollX = 0; } else if (newScrollX > maxLength) { newScrollX = maxLength; } itemRoot.scrollTo(newScrollX, 0); } break; case MotionEvent.ACTION_UP: { int scrollX = itemRoot.getScrollX(); int newScrollX = scrollX + mlastX - x; if (scrollX > maxLength / 2) { newScrollX = maxLength; } else { newScrollX = 0; } // startScroll(int startX, int startY, int dx, int dy) /** * startX:開始移动的X坐标 startY開始移动的Y坐标 * dx:沿X轴移动距离,可正可负,为正时。子控件向左移动;为负时,子控件向右移动 * dy:沿Y轴移动距离,相同,为正时,子控件向上移动;为负时。子控件向下移动 duration:整个移动过程,所耗费时长 */ mScroller.startScroll(scrollX, 0, newScrollX - scrollX, 0); invalidate(); } break; } mlastX = x; return super.onTouchEvent(event); } private int dipToPx(Context context, int dip) { return (int) (dip * context.getResources().getDisplayMetrics().density + 0.5f); } /** * computeScroll()函数。不是Scroller的函数,而是VIEW的函数, * 当调用invaidate或者postInvalidate重绘时就会调用computeScroll() 来重绘与scroller有关的View部分, */ @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { itemRoot.scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); } invalidate(); } }
************************************************升级********************************************
activity_main.xml
<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" tools:context="com.harvic.scrollviewultimate.MainActivity" > <com.harvic.scrollviewultimate.MyListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
item_layout.xml
<?xml version="1.0" encoding="utf-8"? > <com.harvic.scrollviewultimate.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lin_root" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:minHeight="120dp"> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#0000ff" android:gravity="center" android:textSize="25dp" /> <TextView android:id="@+id/del" android:layout_width="200dp" android:layout_height="fill_parent" android:background="#ffff00" android:text="删除" android:textSize="25dp" android:textColor="#ffffff" android:gravity="center" /> </com.harvic.scrollviewultimate.MyLinearLayout>
MainActivity
package com.harvic.scrollviewultimate; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import java.util.ArrayList; import java.util.List; import com.harvic.scrollviewultimate.MergeListAdapter.DataHolder; public class MainActivity extends Activity implements View.OnClickListener,MyLinearLayout.OnScrollListener{ private MyListView listView; private MergeListAdapter adapter; private MyLinearLayout mLastScrollView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (MyListView)findViewById(R.id.listview); final List<DataHolder> items = new ArrayList<DataHolder>(); for(int i=0;i<20;i++){ DataHolder item = new DataHolder(); item.title = "第"+i+"项"; items.add(item); } adapter = new MergeListAdapter(this,items,this,this); listView.setAdapter(adapter); } @Override public void onClick(View v) { if (v.getId() == R.id.del){ int position = listView.getPositionForView(v); adapter.removeItem(position); } } @Override public void OnScroll(MyLinearLayout view) { if (mLastScrollView != null){ mLastScrollView.smoothScrollTo(0,0); } mLastScrollView = view; } }
MyListView
package com.harvic.scrollviewultimate; import com.harvic.scrollviewultimate.MergeListAdapter.DataHolder; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ListView; public class MyListView extends ListView { private MyLinearLayout mCurView; public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { int position = pointToPosition(x, y); if (position != INVALID_POSITION) { DataHolder data = (DataHolder) getItemAtPosition(position); mCurView = data.rootView; } } break; default: break; } if (mCurView != null){ mCurView.disPatchTouchEvent(event); } return super.onTouchEvent(event); } }
MergeListAdapter
package com.harvic.scrollviewultimate; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.TextView; import java.util.ArrayList; import java.util.List; public class MergeListAdapter extends BaseAdapter { private Context mContext; private LayoutInflater mInflater; private List<DataHolder> mDataList = new ArrayList<DataHolder>(); private View.OnClickListener mDelClickListener; private MyLinearLayout.OnScrollListener mScrollListener; public MergeListAdapter(Context context, List<DataHolder> dataList, View.OnClickListener delClickListener,MyLinearLayout.OnScrollListener listener) { mContext = context; mInflater = LayoutInflater.from(context); if (dataList != null && dataList.size() > 0) { mDataList.addAll(dataList); } mDelClickListener = delClickListener; mScrollListener = listener; } public void removeItem(int position) { mDataList.remove(position); notifyDataSetChanged(); } @Override public int getCount() { return mDataList.size(); } @Override public Object getItem(int position) { return mDataList.get(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.getTag() == null) { convertView = mInflater.inflate(R.layout.item_layout, parent, false); holder = new ViewHolder(); holder.title = (TextView) convertView.findViewById(R.id.title); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } DataHolder item = mDataList.get(position); holder.title.setText(item.title); item.rootView = (MyLinearLayout) convertView.findViewById(R.id.lin_root); item.rootView.scrollTo(0, 0); item.rootView.setOnScrollListener(mScrollListener); //点击删除实现方法二:交由外部处理: TextView delTv = (TextView) convertView.findViewById(R.id.del); delTv.setOnClickListener(mDelClickListener); return convertView; } private static class ViewHolder { public TextView title; } public static class DataHolder { public String title; public MyLinearLayout rootView; } }
MyLinearLayout
package com.harvic.scrollviewultimate; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.animation.LinearInterpolator; import android.widget.LinearLayout; import android.widget.Scroller; /** * Created by enwei.zew on 2015/4/28. */ public class MyLinearLayout extends LinearLayout { private int mlastX = 0; private final int MAX_WIDTH = 200; private Context mContext; private Scroller mScroller; private OnScrollListener mScrollListener; public static interface OnScrollListener { public void OnScroll(MyLinearLayout view); } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mScroller = new Scroller(context, new LinearInterpolator(context, null)); } public void disPatchTouchEvent(MotionEvent event) { int maxLength = dipToPx(mContext, MAX_WIDTH); int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { } break; case MotionEvent.ACTION_MOVE: { int scrollX = this.getScrollX(); int newScrollX = scrollX + mlastX - x; if (newScrollX < 0) { newScrollX = 0; } else if (newScrollX > maxLength) { newScrollX = maxLength; } this.scrollTo(newScrollX, 0); } break; case MotionEvent.ACTION_UP: { int scrollX = this.getScrollX(); int newScrollX = scrollX + mlastX - x; if (scrollX > maxLength / 2) { newScrollX = maxLength; mScrollListener.OnScroll(this); } else { newScrollX = 0; } mScroller.startScroll(scrollX, 0, newScrollX - scrollX, 0); invalidate(); } break; } mlastX = x; } public void setOnScrollListener(OnScrollListener scrollListener) { mScrollListener = scrollListener; } public void smoothScrollTo(int destX, int destY) { int scrollX = getScrollX(); int delta = destX - scrollX; mScroller.startScroll(scrollX, 0, delta, 0); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { this.scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); } invalidate(); } private int dipToPx(Context context, int dip) { return (int) (dip * context.getResources().getDisplayMetrics().density + 0.5f); } }
时间: 2024-10-09 20:00:23