标签:android style blog http java color
原文:http://blog.csdn.net/singwhatiwanna/article/details/17515543
最近公司项目需用到微信滑动拉出按钮的效果,发现一位牛人已经实现了相关效果,但控件仍与业务代码存有耦合,于是花了点时间做了些去耦合,并于此进行记录,以防遗忘。
个人认为耦合主要在于两点:
第一点是SlideListView中的onTouchEvent
通过获取item间接得到SlideView,但这样会引入外部数据类MessageItem。
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
int x = (int) event.getX();
int y = (int) event.getY();
//我们想知道当前点击了哪一行
int position = pointToPosition(x, y);
Log.e(TAG, "postion=" + position);
if (position != INVALID_POSITION) {
//得到当前点击行的数据从而取出当前行的item。
//可能有人怀疑,为什么要这么干?为什么不用getChildAt(position)?
//因为ListView会进行缓存,如果你不这么干,有些行的view你是得不到的。
MessageItem data = (MessageItem) getItemAtPosition(position);
mFocusedItemView = data.slideView;
Log.e(TAG, "FocusedItemView=" + mFocusedItemView);
}
}
default:
break;
}
...
}
本人认为将以下代码
int position = pointToPosition(x, y);
if (position != INVALID_POSITION) {
MessageItem data = (MessageItem) getItemAtPosition(position);
mFocusedItemView = data.slideView;
}
修改为:
int position = pointToPosition(x, y);
if (position != INVALID_POSITION) {
int firstPos = getFirstVisiblePosition();
mSlideView = (SlideView) getChildAt(position - firstPos);
}
即可。由于pointToPosition返回的是ListView所有item中被点击的item的position,而listview只会缓存可见的item,因此getChildAt()的时候,需要通过减去getFirstVisiblePosition()来计算被点击的item在可见items中的位置。如此则能够去掉外部数据类MessageItem给控件带来的耦合,同时MessageItem不再需要内部成员slideView。
public class MessageItem {
public int iconRes;
public String title;
public String msg;
public String time;
}
第二点是slide_view_merge.xml中holder的宽度被固定为120dp
<?xml version="1.0" encoding="utf-8"?> <merge ... <RelativeLayout android:id="@+id/holder" android:layout_width="120dp" android:layout_height="match_parent" android:clickable="true" android:background="@drawable/holder_bg"> ... </RelativeLayout> </merge>
SlideView初始化时再次计算其宽度
SlideView.java:
private void initView() {
mContext = getContext();
// 初始化弹性滑动对象
mScroller = new Scroller(mContext);
// 设置其方向为横向
setOrientation(LinearLayout.HORIZONTAL);
// 将slide_view_merge加载进来
View.inflate(mContext, R.layout.slide_view_merge, this);
mViewContent = (LinearLayout) findViewById(R.id.view_content);
mHolderWidth = Math.round(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
.getDisplayMetrics()));
}
本人顾虑(当然该顾虑可能是多余的)到按钮无法根据字体进行长度扩展,在SlideView初始化时提前计算holder可能所需的空间,确保按钮的可扩展性
修改如下:
<?xml version="1.0" encoding="utf-8"?> <merge ... <RelativeLayout android:id="@+id/holder" android:layout_width="wrap_content" android:layout_height="match_parent" android:clickable="true" android:background="@drawable/holder_bg"> ... </RelativeLayout> </merge>
SlideView.java:
private void initView() {
mContext = getContext();
// 初始化弹性滑动对象
mScroller = new Scroller(mContext);
// 设置其方向为横向
setOrientation(LinearLayout.HORIZONTAL);
// 将slide_view_merge加载进来
View.inflate(mContext, R.layout.slide_view_merge, this);
mViewContent = (LinearLayout) findViewById(R.id.view_content);
mHolder = (RelativeLayout) findViewById(R.id.holder);
mHolder.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
mHolderWidth = mHolder.getMeasuredWidth();
mHolder.setLayoutParams(new LinearLayout.LayoutParams(mHolderWidth, LayoutParams.FILL_PARENT));
}
总体来说,牛人的代码很简洁易用,很符合小弟的口味,十分感谢牛人的无私分享!
关于高仿微信对话列表滑动删除效果代码优化,布布扣,bubuko.com
标签:android style blog http java color
原文地址:http://my.oschina.net/u/1867023/blog/293653