底部弹出DialogFragment
,宽度match parent
,高度wrap content
,有进入动画和退出动画。
/**
* Created by rc on 2017/8/31.
* Description:
* 1.底部弹出
* 2.width match parent ;height wrap content
* 3.show和dismiss有动画
* 4.点击外面dialog dismiss
* 5.添加show(FragmentManager fragmentManager)方法
* 6.已经完成ButterKnife绑定与解绑
*/
public abstract class BaseBottomDialogFragment extends DialogFragment {
protected boolean isAnimation = false;
protected View mRootView;
private Unbinder mUnbinder;
@Override
public void onStart() {
super.onStart();
Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.BOTTOM;
window.setAttributes(params);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
window.getDecorView().setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
dismiss();
return true;
}
});
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRootView = inflater.inflate(getDialogLayoutId(), container, false);
mUnbinder = ButterKnife.bind(this, mRootView);
DialogAnimationUtils.slideToUp(mRootView);
return mRootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setUp();
}
public void show(FragmentManager fragmentManager) {
super.show(fragmentManager, getClass().getSimpleName());
}
protected abstract void setUp();
/**
* @return 返回dialog布局Id
*/
protected abstract
@LayoutRes
int getDialogLayoutId();
@Override
public void dismiss() {
if (isAnimation) {
return;
}
isAnimation = true;
DialogAnimationUtils.slideToDown(mRootView, new DialogAnimationUtils.AnimationListener() {
@Override
public void onFinish() {
isAnimation = false;
BaseBottomDialogFragment.super.dismiss();
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
mUnbinder.unbind();
}
}
DialogAnimationUtils
工具类
/**
* Created by rc on 2017/8/31.
* Description: dialog 动画 工具类
*/
public class DialogAnimationUtils {
public interface AnimationListener {
void onFinish();
}
public static void slideToUp(View view){
Animation slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
slide.setDuration(400);
slide.setFillAfter(true);
slide.setFillEnabled(true);
view.startAnimation(slide);
slide.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
public static void slideToDown(View view, final AnimationListener listener){
Animation slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, 1.0f);
slide.setDuration(400);
slide.setFillAfter(true);
slide.setFillEnabled(true);
view.startAnimation(slide);
slide.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (listener != null) {
listener.onFinish();
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
}
advancedrecyclerview
提供了很多强大的功能,但是相对的使用成本还是有点大,因为项目侧滑的样式基本都一样,故基于项目,封装了一下~~
/**
* Created by rc on 2017/8/31.
* Description: 基于advanceRecyclerView侧滑的封装
*/
public abstract class BaseSwipeAdapter<T, V extends WrapAbstractSwipeableItemViewHolder>
extends RecyclerView.Adapter<V> implements SwipeableItemAdapter<V> {
protected List<T> mList;
private interface Swipeable extends SwipeableItemConstants {
}
public BaseSwipeAdapter(List<T> list) {
mList = list;
// requires stable ID, and also
// have to implement the getItemId() method appropriately
setHasStableIds(true);
}
@Override
public long getItemId(int position) {
return getContentItemId(position);
}
/**
* @return 返回不同的Id
*/
protected abstract long getContentItemId(int position);
@Override
public V onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(getHolderLayoutId(), parent, false);
return getViewHolder(view);
}
protected abstract V getViewHolder(View view);
protected abstract
@LayoutRes
int getHolderLayoutId();
@Override
public void onBindViewHolder(V holder, int position) {
onBindContentViewHolder(holder, position, mList.get(position));
}
protected abstract void onBindContentViewHolder(V holder, int position, T t);
@Override
public int getItemCount() {
return mList == null ? 0 : mList.size();
}
/**
* @param holder holder
* @param position 当前的位置
* @param x touch x 位置
* @param y touch y 位置
* @return 滑动的方向
*/
@Override
public int onGetSwipeReactionType(V holder, int position, int x, int y) {
if (ViewUtils.hitTest(holder.getSwipeableContainerView(), x, y)) {
return Swipeable.REACTION_CAN_SWIPE_BOTH_H;
} else {
return Swipeable.REACTION_CAN_NOT_SWIPE_BOTH_H;
}
}
/**
* 该方法用于在滑动的时候,动态设置背景是否可见
*
* @param holder holder
* @param position 当前位置
* @param type 当前滑动的类型
*/
@Override
public void onSetSwipeBackground(V holder, int position, int type) {
if (type == Swipeable.DRAWABLE_SWIPE_NEUTRAL_BACKGROUND) {
holder.getBeBindView().setVisibility(View.GONE);
} else {
holder.getBeBindView().setVisibility(View.VISIBLE);
}
}
/**
* 松手后进行回调
*
* @param holder viewholder
* @param position 点击item的position
* @param result 松手收的状态,打开 or 闭合
* @return 对应的处理事件
*/
@Override
public SwipeResultAction onSwipeItem(V holder, int position, int result) {
switch (result) {
case Swipeable.RESULT_SWIPED_LEFT:
//向左边滑动
return new SwipeLeftResultAction(this, position);
case Swipeable.RESULT_SWIPED_RIGHT://向右滑动
case Swipeable.RESULT_CANCELED://取消
default:
if (position != RecyclerView.NO_POSITION) {
return new UnpinResultAction(this, position);
} else {
return null;
}
}
}
private class SwipeLeftResultAction extends SwipeResultActionMoveToSwipedDirection {
private BaseSwipeAdapter mAdapter;
private int position;
public SwipeLeftResultAction(BaseSwipeAdapter adapter, int position) {
mAdapter = adapter;
this.position = position;
}
@Override
protected void onPerformAction() {
super.onPerformAction();
//刷新数据,标志打开
onSwipeLeftAction(mAdapter, position, mList.get(position));
}
@Override
protected void onCleanUp() {
super.onCleanUp();
mAdapter = null;
}
}
private class UnpinResultAction extends SwipeResultActionDefault {
private BaseSwipeAdapter mAdapter;
private int position;
public UnpinResultAction(BaseSwipeAdapter adapter, int position) {
this.mAdapter = adapter;
this.position = position;
}
@Override
protected void onPerformAction() {
super.onPerformAction();
//刷新数据,标志关闭
onUnPinAction(mAdapter, position, mList.get(position));
}
@Override
protected void onCleanUp() {
super.onCleanUp();
mAdapter = null;
}
}
protected abstract void onUnPinAction(BaseSwipeAdapter adapter, int position, T t);
protected abstract void onSwipeLeftAction(BaseSwipeAdapter adapter, int position, T t);
public void addItems(List<T> list) {
mList.clear();
mList.addAll(list);
notifyItemRangeInserted(0, mList.size());
}
}
/**
* Created by rc on 2017/9/1.
* Description:
*/
public abstract class WrapAbstractSwipeableItemViewHolder extends AbstractSwipeableItemViewHolder {
public WrapAbstractSwipeableItemViewHolder(View itemView) {
super(itemView);
}
public abstract View getBeBindView();
}
public class ViewUtils {
public static boolean hitTest(View v, int x, int y) {
final int tx = (int) (ViewCompat.getTranslationX(v) + 0.5f);
final int ty = (int) (ViewCompat.getTranslationY(v) + 0.5f);
final int left = v.getLeft() + tx;
final int right = v.getRight() + tx;
final int top = v.getTop() + ty;
final int bottom = v.getBottom() + ty;
return (x >= left) && (x <= right) && (y >= top) && (y <= bottom);
}
}
/**
* @param top
* @param dy 手指移动偏移量 上拉为正,下拉为负
* @param minValue 允许移动到的最小值
* @param maxValue 允许移动到的最大值
* @return
*/
public int getAreaValue(int top, int dy, int minValue, int maxValue) {
//不允许继续往上拉
if (top + dy < minValue) {
return minValue - top;
}
//不允许继续往下拉
if (top + dy > maxValue) {
return maxValue - top;
}
//返回正常的偏移量
return dy;
}
2.根据触摸事件,返回是否点击当前view
/**
* 根据触摸事件,返回是否点击当前view
*
*
* @param view 需要判断的view
* @param event 触摸事件
* @return true 点击
*/
public boolean isClickView(View view, MotionEvent event) {
Rect rect = new Rect();
view.getHitRect(rect);
return rect.contains(((int) event.getX()), ((int) event.getY()) + getScrollY());
}