QQ视差特效和ListView侧滑删除
如图所示是效果图,当向下拉时,图片会被拉出来,松手后恢复。和ListView的侧滑删除
1.视差特效
首先图片是通过addHeaderView加上去的,所以在设置Adapter前先设置一个View来作为头布局,图片的设置android:scaleType="centerCrop"
然后可以重写ListView主要是用通过overScrollBy来实现图片的拉出效果的,当拉出图片绘制后,重写onTouchEvent方法MotionEvent.ACTION_UP
实现回弹
如下是主代码
- package com.demo.sb.main;
- import com.demo.sb.adapter.ParallacAdapter;
- import com.demo.sb.widget.MyParallaxListView;
- import com.demo.suibian.R;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.Window;
- import android.view.ViewTreeObserver.OnGlobalLayoutListener;
- import android.widget.ImageView;
- /**
- * 视差特效类型于QQ空间上的
- *
- * @author Administrator
- *
- */
- public class MActivity_Parallac extends Activity {
- private MyParallaxListView mListView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.mactivity_parallax);
- mListView = (MyParallaxListView) findViewById(R.id.lv);
- mListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
- // 加上Header
- final View mHeaderView = View.inflate(MActivity_Parallac.this,
- R.layout.viewheader, null);
- final ImageView mImage = (ImageView) mHeaderView.findViewById(R.id.iv);
- mListView.addHeaderView(mHeaderView);
- mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(
- new OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- // TODO Auto-generated method stub
- mListView.setParallaxImage(mImage);
- mHeaderView.getViewTreeObserver()
- .removeGlobalOnLayoutListener(this);
- }
- });
- // mListView.setAdapter(new SuibianAdapter(this));
- mListView.setAdapter(new ParallacAdapter(this));
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <ImageView
- android:id="@+id/iv"
- android:layout_width="match_parent"
- android:layout_height="200dp"
- android:contentDescription="@null"
- android:scaleType="centerCrop"
- android:src="@drawable/d" />
- </LinearLayout>
重写的ListView
- package com.demo.sb.widget;
- import com.nineoldandroids.animation.ValueAnimator;
- import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.animation.Animation;
- import android.view.animation.OvershootInterpolator;
- import android.view.animation.Transformation;
- import android.widget.ImageView;
- import android.widget.ListView;
- public class MyParallaxListView extends ListView{
- private ImageView mImage;
- private int drawableHeight;
- private int mOriginalHeight;
- public MyParallaxListView(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
- public MyParallaxListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- // TODO Auto-generated constructor stub
- }
- public MyParallaxListView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- // TODO Auto-generated constructor stub
- }
- /**
- * 设置ImageView图片,拿到引用
- * @param mImage
- */
- public void setParallaxImage(ImageView mImage) {
- // TODO Auto-generated method stub
- this.mImage = mImage;
- mOriginalHeight = mImage.getHeight();
- drawableHeight = mImage.getDrawable().getIntrinsicHeight();
- Log.d("jiejie", "height: " + mOriginalHeight + " drawableHeight: " + drawableHeight);
- }
- @Override
- protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
- int scrollY, int scrollRangeX, int scrollRangeY,
- int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
- // TODO Auto-generated method stub
- // deltaY : 竖直方向的瞬时偏移量 / 变化量 dx 顶部到头下拉为-, 底部到头上拉为+
- // scrollY : 竖直方向的偏移量 / 变化量
- // scrollRangeY : 竖直方向滑动的范围
- // maxOverScrollY : 竖直方向最大滑动范围
- // isTouchEvent : 是否是手指触摸滑动, true为手指, false为惯性
- Log.d("jiejie", "deltaY: " +deltaY + " scrollY: " + scrollY + " scrollRangeY: " + scrollRangeY
- + " maxOverScrollY: " + maxOverScrollY + " isTouchEvent: " + isTouchEvent);
- //手指拉动并且是下拉
- if(isTouchEvent && deltaY <0){
- //把拉动的瞬时变化量的绝对值交给Header,就可以实现放大的效果了
- if(mImage.getHeight() <=drawableHeight ){
- int newHeight = (int)(mImage.getHeight() + Math.abs(deltaY / 3.0f));
- //高度不超过图片最大高度时,才让其生效
- mImage.getLayoutParams().height = newHeight;
- mImage.requestLayout();
- }
- }
- return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
- scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
- }
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- // TODO Auto-generated method stub
- switch (ev.getAction()) {
- case MotionEvent.ACTION_UP:
- //执行回弹动画,方式一:属性动画
- //从当前高度mImage.getHeight(),执行动画到原始高度mOriginalHeight
- final int startHeight = mImage.getHeight();
- final int endHeight = mOriginalHeight;
- //ValueAnimator(startHeight,endHeight);
- //执行回弹动画,方式二:自定义Animation
- ResetAnimation animation = new ResetAnimation(mImage,startHeight,endHeight);
- startAnimation(animation);
- break;
- default:
- break;
- }
- return super.onTouchEvent(ev);
- }
- private void ValueAnimator(final int startHeight, final int endHeight) {
- // TODO Auto-generated method stub
- ValueAnimator mValueAnimator = ValueAnimator.ofInt(1);
- mValueAnimator.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- // TODO Auto-generated method stub
- float fraction = arg0.getAnimatedFraction();
- //percent 0.0-1.0
- Integer newHeight = evaluate(fraction, startHeight, endHeight);
- mImage.getLayoutParams().height = newHeight;
- mImage.requestLayout();
- }
- });
- mValueAnimator.setInterpolator(new OvershootInterpolator());
- mValueAnimator.setDuration(800);
- mValueAnimator.start();
- }
- /**
- * 类型估值器
- * @param fraction
- * @param startValue
- * @param endValue
- * @return
- */
- public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
- int startInt = startValue;
- return (int)(startInt + fraction * (endValue - startInt));
- }
- /**
- * 执行的动画
- * @author Administrator
- *
- */
- private class ResetAnimation extends Animation{
- private final ImageView mImageView;
- private final int startHeight;
- private final int endHeight;
- public ResetAnimation(ImageView mImage, int startHeight, int endHeight) {
- // TODO Auto-generated constructor stub
- this.mImageView = mImage;
- this.startHeight = startHeight;
- this.endHeight = endHeight;
- /**
- * Interpolator被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速)
- * decelerated(减速),repeated(重复),bounced(弹跳)等
- *
- * OvershootInterpolator 向前甩一定值后再回到原来位置
- */
- setInterpolator(new OvershootInterpolator());
- //设置动画的执行时长
- setDuration(800);
- }
- @Override
- protected void applyTransformation(float interpolatedTime,
- Transformation t) {
- // TODO Auto-generated method stub
- System.out.println(interpolatedTime );
- //interpolatedTime 0.0f -> 1.0f
- Integer newHeightInteger = evaluate(interpolatedTime, startHeight, endHeight);
- mImageView.getLayoutParams().height = newHeightInteger;
- mImageView.requestLayout();
- super.applyTransformation(interpolatedTime, t);
- }
- }
- }
2.实现ListView的侧滑删除功能
自定义的布局来显示侧滑的功能
- package com.demo.sb.adapter;
- import com.demo.sb.utils.DensityUtil;
- import android.content.Context;
- import android.graphics.Rect;
- import android.support.v4.view.ViewCompat;
- import android.support.v4.widget.ViewDragHelper;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- import android.widget.FrameLayout;
- /**
- * 侧拉删除控件
- *
- * @author Administrator
- *
- */
- public class SwipeLayout extends FrameLayout {
- private Status status = Status.Close;
- private OnSwipeLayoutListener swipeLayoutListener;
- public Status getStatus() {
- return status;
- }
- public void setStatus(Status status) {
- this.status = status;
- }
- public OnSwipeLayoutListener getSwipeLayoutListener() {
- return swipeLayoutListener;
- }
- public void setSwipeLayoutListener(OnSwipeLayoutListener swipeLayoutListener) {
- this.swipeLayoutListener = swipeLayoutListener;
- }
- public static enum Status {
- Close, Open, Draging
- }
- public static interface OnSwipeLayoutListener {
- void onClose(SwipeLayout mSwipeLayout);
- void onOpen(SwipeLayout mSwipeLayout);
- void onDraging(SwipeLayout mSwipeLayout);
- // 要去关闭
- void onStartClose(SwipeLayout mSwipeLayout);
- // 要去开启
- void onStartOpen(SwipeLayout mSwipeLayout);
- }
- public SwipeLayout(Context context) {
- this(context, null);
- // TODO Auto-generated constructor stub
- }
- public SwipeLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- // TODO Auto-generated constructor stub
- }
- public SwipeLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- // TODO Auto-generated constructor stub
- mDragHelper = ViewDragHelper.create(this, 1.0f, mCallback);
- }
- ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
- // c . 重写监听
- @Override
- public boolean tryCaptureView(View arg0, int arg1) {
- // TODO Auto-generated method stub
- return true;
- }
- // 限定移动范围
- public int clampViewPositionHorizontal(View child, int left, int dx) {
- // left
- if (child == mFrontView) {
- if (left > 0) {
- return 0;
- } else if (left < -mRange) {
- return -mRange;
- }
- } else if (child == mBackView) {
- if (left > mWidth) {
- return mWidth;
- } else if (left < mWidth - mRange) {
- return mWidth - mRange;
- }
- }
- return left;
- };
- public void onViewPositionChanged(View changedView, int left, int top,
- int dx, int dy) {
- // 专递事件
- if (changedView == mFrontView) {
- mBackView.offsetLeftAndRight(dx);
- } else if (changedView == mBackView) {
- mFrontView.offsetLeftAndRight(dx);
- }
- despatchSwipeEvent();
- // 兼容老版本
- invalidate();
- };
- public void onViewReleased(View releasedChild, float xvel, float yvel) {
- if (xvel == 0 && mFrontView.getLeft() < -mRange / 2.0f) {
- open();
- } else if (xvel < 0) {
- open();
- } else {
- close();
- }
- };
- };
- private ViewDragHelper mDragHelper;
- private View mBackView;
- private View mFrontView;
- private int mHeight;
- private int mWidth;
- private int mRange;
- // b. 专递触摸事件
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- // TODO Auto-generated method stub
- return mDragHelper.shouldInterceptTouchEvent(ev);
- }
- protected void despatchSwipeEvent() {
- // TODO Auto-generated method stub
- if (swipeLayoutListener != null) {
- swipeLayoutListener.onDraging(this);
- }
- // 记录上一次的状态
- Status preStatus = status;
- // 更新当前的状态
- status = updateStatus();
- if (preStatus != status && swipeLayoutListener != null) {
- if (status == Status.Close) {
- swipeLayoutListener.onClose(this);
- } else if (status == Status.Open) {
- swipeLayoutListener.onOpen(this);
- } else if (status == Status.Draging) {
- if (preStatus == Status.Close) {
- swipeLayoutListener.onStartOpen(this);
- } else if (preStatus == Status.Open) {
- swipeLayoutListener.onStartClose(this);
- }
- }
- }
- }
- private Status updateStatus() {
- int left = mFrontView.getLeft();
- if (left == 0) {
- return Status.Close;
- } else if (left == -mRange) {
- return Status.Open;
- }
- return Status.Draging;
- }
- public void close() {
- // TODO Auto-generated method stub
- DensityUtil.showToast(getContext(), "Close");
- close(true);
- }
- public void close(boolean isSmooth) {
- // TODO Auto-generated method stub
- int finalLeft = 0;
- if (isSmooth) {
- // 开始动画
- if (mDragHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)) {
- ViewCompat.postInvalidateOnAnimation(this);
- }
- } else {
- layoutContent(false);
- }
- }
- public void open() {
- DensityUtil.showToast(getContext(), "Open");
- open(true);
- }
- public void open(boolean isSmooth) {
- int finalLeft = -mRange;
- if (isSmooth) {
- // 开始动画
- if (mDragHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)) {
- ViewCompat.postInvalidateOnAnimation(this);
- }
- } else {
- layoutContent(true);
- }
- }
- @Override
- public void computeScroll() {
- // TODO Auto-generated method stub
- super.computeScroll();
- if (mDragHelper.continueSettling(true)) {
- ViewCompat.postInvalidateOnAnimation(this);
- }
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- // TODO Auto-generated method stub
- try {
- mDragHelper.processTouchEvent(event);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return true;
- }
- @Override
- protected void onLayout(boolean changed, int left, int top, int right,
- int bottom) {
- // TODO Auto-generated method stub
- super.onLayout(changed, left, top, right, bottom);
- // 摆放位置
- layoutContent(false);
- }
- private void layoutContent(boolean isOpen) {
- // TODO Auto-generated method stub
- // 摆放钱View
- Rect frontRect = computeFrontViewRect(isOpen);
- mFrontView.layout(frontRect.left, frontRect.top, frontRect.right,
- frontRect.bottom);
- // 摆放后View
- Rect backRect = computeBackViewViaFront(frontRect);
- mBackView.layout(backRect.left, backRect.top, backRect.right,
- backRect.bottom);
- // 调整顺序,把mFrontView前置
- bringChildToFront(mFrontView);
- }
- private Rect computeBackViewViaFront(Rect frontRect) {
- // TODO Auto-generated method stub
- int left = frontRect.right;
- return new Rect(left, 0, left + mRange, 0 + mHeight);
- }
- private Rect computeFrontViewRect(boolean isOpen) {
- // TODO Auto-generated method stub
- int left = 0;
- if (isOpen) {
- left = -mRange;
- }
- return new Rect(left, 0, left + mWidth, 0 + mHeight);
- }
- @Override
- protected void onFinishInflate() {
- // TODO Auto-generated method stub
- super.onFinishInflate();
- mBackView = getChildAt(0);
- mFrontView = getChildAt(1);
- }
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- // TODO Auto-generated method stub
- super.onSizeChanged(w, h, oldw, oldh);
- mHeight = mFrontView.getMeasuredHeight();
- mWidth = mFrontView.getMeasuredWidth();
- mRange = mBackView.getMeasuredWidth();
- }
- }
- package com.demo.sb.adapter;
- import java.util.ArrayList;
- import com.demo.sb.adapter.SwipeLayout.OnSwipeLayoutListener;
- import com.demo.sb.utils.DensityUtil;
- import com.demo.suibian.R;
- import android.app.AlertDialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.TextView;
- public class ParallacAdapter extends BaseAdapter {
- private Context context;
- private int[] cost = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
- private String[] nameStrings = { "宋江", "卢俊义", "吴用", "公孙胜", "关胜", "林冲",
- "秦明", "呼延灼", "花荣", "柴进", "李应", "鲁智深", "索超", "戴宗" };
- private ArrayList<SwipeLayout> opendItems;
- public ParallacAdapter(Context context) {
- super();
- this.context = context;
- opendItems = new ArrayList<SwipeLayout>();
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return nameStrings.length;
- }
- @Override
- public Object getItem(int arg0) {
- // TODO Auto-generated method stub
- return nameStrings[arg0];
- }
- @Override
- public long getItemId(int arg0) {
- // TODO Auto-generated method stub
- return arg0;
- }
- @Override
- public View getView(final int arg0, View arg1, ViewGroup arg2) {
- // TODO Auto-generated method stub
- ViewHolder holder;
- if (arg1 == null) {
- holder = new ViewHolder();
- arg1 = View.inflate(context, R.layout.item_parallac_list, null);
- holder.tv_del = (TextView) arg1.findViewById(R.id.tv_item_pardel);
- holder.tv_name = (TextView) arg1
- .findViewById(R.id.item_parallax_name);
- holder.tv_fight = (TextView) arg1
- .findViewById(R.id.item_parallax_fight);
- holder.tv_call = (TextView) arg1.findViewById(R.id.tv_item_parcall);
- arg1.setTag(holder);
- } else {
- holder = (ViewHolder) arg1.getTag();
- }
- SwipeLayout sLayout = (SwipeLayout) arg1;
- sLayout.setSwipeLayoutListener(new OnSwipeLayoutListener() {
- @Override
- public void onStartOpen(SwipeLayout mSwipeLayout) {
- // TODO Auto-generated method stub
- // 要去开启时,先遍历所有已打开的条目,逐个关闭
- for (SwipeLayout layout : opendItems) {
- layout.close();
- }
- opendItems.clear();
- }
- @Override
- public void onStartClose(SwipeLayout mSwipeLayout) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onOpen(SwipeLayout mSwipeLayout) {
- // TODO Auto-generated method stub
- opendItems.add(mSwipeLayout);
- }
- @Override
- public void onDraging(SwipeLayout mSwipeLayout) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onClose(SwipeLayout mSwipeLayout) {
- // TODO Auto-generated method stub
- opendItems.remove(mSwipeLayout);
- }
- });
- holder.tv_name.setText("名字为 :" + nameStrings[arg0]);
- holder.tv_fight.setText("战斗力: " + cost[arg0]);
- holder.tv_del.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- // TODO Auto-generated method stub
- DensityUtil.showToast(context, "第" + arg0 + "个 为"
- + nameStrings[arg0]);
- }
- });
- holder.tv_call.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- // TODO Auto-generated method stub
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle("标题!!!");
- builder.setCancelable(false);
- builder.setMessage("设置警告,是否确定删除,删除是不可逆的奥");
- builder.setPositiveButton("确定",
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface perent, int arg1) {
- // TODO Auto-generated method stub
- DensityUtil.showToast(context,
- nameStrings[arg0]);
- }
- });
- builder.setNegativeButton("取消",
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface arg0, int arg1) {
- // TODO Auto-generated method stub
- }
- });
- builder.create().show();
- }
- });
- return arg1;
- }
- static class ViewHolder {
- TextView tv_del;
- TextView tv_name;
- TextView tv_fight;
- TextView tv_call;
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <com.demo.sb.adapter.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/sl"
- android:layout_width="match_parent"
- android:layout_height="80dp"
- android:background="#4000" >
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/tv_item_parcall"
- android:layout_width="100dp"
- android:layout_height="match_parent"
- android:background="#666"
- android:gravity="center"
- android:text="call"
- android:textColor="#fff" />
- <TextView
- android:id="@+id/tv_item_pardel"
- android:layout_width="100dp"
- android:layout_height="match_parent"
- android:background="#f00"
- android:gravity="center"
- android:text="Delete"
- android:textColor="#fff" />
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#4fff"
- android:padding="5dp" >
- <ImageView
- android:id="@+id/item_view"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:contentDescription="@null"
- android:scaleType="fitXY"
- android:src="@drawable/a" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="10dp" >
- <TextView
- android:id="@+id/item_parallax_name"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textColor="#f00"
- android:textSize="20sp" />
- <TextView
- android:id="@+id/item_parallax_fight"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="10dp"
- android:text=""
- android:textColor="#5000"
- android:textSize="16sp" />
- </LinearLayout>
- </LinearLayout>
- </com.demo.sb.adapter.SwipeLayout>
QQ视差特效和ListView侧滑删除的更多相关文章
- QQ 特效学习 二 侧滑删除
上篇文章: http://www.cnblogs.com/xurui1995/p/5798631.html 今天来写不仅是qq而且在别的软件上也特别流行的侧滑删除 其实套路和前篇的一样,一个自定义Vi ...
- listview侧滑删除
自定义Listview,向左滑动,右边刚好显示删除按钮: public class SlideListView extends ListView { private int mScreenWidth; ...
- 史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。
重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...
- Android 自定义ListView Item侧滑删除
本程序是基于网上开源项目修改而来,具体来源忘了,懒得搜了,如果有不合适的地方,请原作者联系我,我会及时回复和处理的! 该例子程序中主要包含两个ListView,一个是实现侧滑删除,一个是侧滑出菜单,代 ...
- 9.视差特效、回弹动画、overScrollBy
视差特效 * 应用场景: 微信朋友圈, QQ空间, 微博个人展示,向下拉出,松开回弹* 功能实现: > 1. 重写overScrollBy > 2. 松手之后执行动画, 类型估值器 . ...
- ListView滑动删除效果实现
通过继承ListView然后结合PopupWindow实现 首先是布局文件: delete_btn.xml:这里只需要一个Button <?xml version="1.0" ...
- 记一个SwipeMenuListView侧滑删除错乱的Bug
做侧滑删除网上有很多方案,比如重写Listview实现滑动的监听,今天说下一个SwipeListView,这个是之前一个朋友在网上开源的一个封装组件,能够适用于多种情况,项目地址:https://gi ...
- Android实现RecyclerView侧滑删除和长按拖拽-ItemTouchHelper
RecyclerView这个被誉为ListView和GirdView的替代品,它的用法在之前的一篇博文中就已经讲过了,今天我们就来实现RecyclerView的侧滑删除和长按拖拽功能,实现这两个功能我 ...
- android--------ListView和ExpandableListView的侧滑删除操作
本案例主要实现了ListView和ExpandableListView的侧滑删除操作功能 效果图: ListView的Adapter类 private class SlideAdapter exten ...
随机推荐
- searchableselect不支持onchange的问题
1.找到jquery.searchableSelect.js 2.找到selectItem函数 修改里面的方法,加入自定义你要回调的函数 selectItem: function(item){ //L ...
- [转载]寻找两个有序数组中的第K个数或者中位数
http://blog.csdn.net/realxie/article/details/8078043 假设有长度分为为M和N的两个升序数组A和B,在A和B两个数组中查找第K大的数,即将A和B按升序 ...
- SQL调优 - Hints指定索引 解决慢查询案例
背景 每当交易高峰时期,可能会暴露一些平时无法发现的问题,机遇和挑战并存.下面聊聊最近解决的一个案例,因为执行计划走错导致慢查询,进而引发应用线程阻塞.线程池爆满,最后应用功能瘫痪.如何标本兼治的解决 ...
- saiku 展示优化
saiku版本:3.7.4 下面是修改步骤,如果觉得麻烦,可以直接下载源代码:https://github.com/lihehuo/saiku 1.关闭自动执行 修改文件:saiku-ui/js/sa ...
- java 使用 ScriptEngineManager 解析逻辑表达式
将表达式替换成js使用的文本格式.然后带入eval函数. public class JieXi { public static void main(String[] args) throws Exce ...
- 在unity5中减少Draw Calls(SetPass Calls)[转]
在unity5中减少Draw Calls(SetPass Calls) 我一直工作于unity5支持的Standard Shader(标准着色器)上,并且做了一些关于如何有效地减少draw cal ...
- Oracle数据库入门——pctfree和pctused详解
一.建立表时候,注意PCTFREE参数的作用 PCTFREE:为一个块保留的空间百分比,表示数据块在什么情况下可以被insert,默认是10,表示当数据块的可用空间低于10%后,就不可以被insert ...
- 精确计算TFS中新增以及更改的代码行数
<configuration> <configSections> <section name="LOCTargets" type="Cons ...
- 安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)
在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...
- 解决php中echo出来的汉子乱码
问的人太多了,就列出来展示给大家! 需要了解的概念: Content-Type:用于定义用户的浏览器或相关设备如何显示将要加载的数据,或者如何处理将要加载的数据 MIME:MIME类型就是设定某种扩展 ...