仿魅族应用商店应用详情页效果

趁着UI妹子还没有把图切好,我这几天简直闲得不行,所以得空学习一下CoordinatorLayout的使用,当然这里不会是想特地写一篇文章来介绍它的基本用法,因为这个在网上有太多的资料。学习完基础我们就可以深入其中,学习其精髓。那么CoordinatorLayout最精髓的地方是什么呢?就是Behaviour。
那么什么是Behaviour呢?可以先看看以下博客
Android——CoordinatorLayout之Behavior入门学习(上)
Android——CoordinatorLayout之Behavior入门学习(下)
感谢博主郭神。

Behaviour使用

一、仿知乎首页

项目中将会使用到知乎首页的效果

zhihu

我们可以看到,底部菜单Tab会随着滑动隐藏和显示

不使用Behaviour

我在第一次思考时是不使用Behaviour,监听AppBarLayout滑动距离进行操作:

bar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                ///下拉:0~-height,上拉:-height~0
                if (verticalOffset != 0) {
                    if (height != 0) {
                        Log.d("Activity", "onOffsetChanged: vertaicalOffset =====" + verticalOffset);
                        //通过滑动距离跟高度计算得到percent值
                        float i = (height + verticalOffset) / height;
                        Log.d("Activity", "onOffsetChanged: i=====" + i);
                        float alpha = 255 * i / 255;
                        Log.d("Activity", "onOffsetChanged: alpha === " + alpha);
                        ViewGroup.LayoutParams params = mBottom.getLayoutParams();
                        //通过percent值对底部Tab的LayoutParams进行修改
                        params.height = (int) (height * alpha);
                        mBottom.requestLayout();
                    }
                }
            }
        });```
这时我遇到一个小问题,就是在快速滑动的时候底部Tab计算会跟不上滑动的速度导致底部Tab的高度不正确
(如下图)

![error](http://upload-images.jianshu.io/upload_images/2605454-50d04a033b273dca.gif?imageMogr2/auto-orient/strip)
那么我是怎样解决的呢?

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Log.d("Activity", "onScrollStateChanged: newState===" + newState);
// LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
int position = layoutManager.findFirstCompletelyVisibleItemPosition();
Log.d("Activity", "onScrollStateChanged: completeItemPosition ====" + position);
if (position == 0 && newState == RecyclerView.SCROLL_STATE_IDLE) {
if (mBottom.getHeight() != height) {
mBottom.getLayoutParams().height = (int) height;
mBottom.requestLayout();
}
}
}

    });```

我这里是通过监听recyclerView的显示item来强制修改,达到目的(这里提供一个解决思路,非最佳)

使用Behaviour

简单自定义一个Behaviour即可达到效果

/**
 * Created by AmatorLee on 2017/7/18.
 */

public class FootBehaviour extends CoordinatorLayout.Behavior<View> {


    public FootBehaviour(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return dependency instanceof AppBarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        //通过AppBarLayout的滑动距离计算percent
        float scaleY = Math.abs(dependency.getY()) / dependency.getHeight();
        //通过percent动态移动我们的view,注意是移动不是修改
        child.setTranslationY(child.getHeight() * scaleY);
        return true;
    }
}```
看看效果

![success](http://upload-images.jianshu.io/upload_images/2605454-d2c1dd241203bd1b.gif?imageMogr2/auto-orient/strip)
#####二、仿魅族应用商店应用详情效果
作为一个多年的魅族手机使用者,看起来魅族的应用商店也挺不错的,来看看要实现的效果(**注:实现效果而非实现实现界面**)

![sheet](http://upload-images.jianshu.io/upload_images/2605454-3b9fc78ca7aaaa87.gif?imageMogr2/auto-orient/strip)

1. 思路一:使用Activity实现,但是这样需要解决的问题有:
  1.  Activity进场/出场动画
  2.     对于滑动的监听
 3. 对状态栏的动态改变

2. 思路二:由于我们这边使用的是Behaviour,而系统给我们提供了一个```BottomSheetBehavior```应该可以完美的给我们解决滑动的问题,但是Activity方面的问题依然存在,然后找到了一个强大的Dialog(```BottomSheetDialog```)和一个DialogFragment(```BottomSheetDialogFragment```),,以我夜观天象应该这个就是实现了``````BottomSheetBehavior```的View,很好很强大。
我们来看看我们是怎样是实现的:
    /**
     * BottomSheetDialog
     */
    Button btnShowDialog = (Button) findViewById(R.id.bottom_pull_sheet);
    mDatas = new ArrayList<>();
    View inflate = getLayoutInflater().inflate(R.layout.dialog_bottom_sheet, null);
    mLeftIcon = inflate.findViewById(R.id.delete);
    mLeftIcon.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (mBottomSheetDialog != null && mBottomSheetDialog.isShowing()) {
                mBottomSheetDialog.dismiss();
            }
        }
    });
    RecyclerView recyclerView = inflate.findViewById(R.id.recyclerView);
    mDatas = new ArrayList<>();
    for (int i = 0; i < 50; i++) {
        mDatas.add("这是第" + i + "个数据");
    }
    recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    Adapter adapter = new Adapter();
    recyclerView.setAdapter(adapter);
    mBottomSheetDialog = new BottomSheetDialog(this);
    mBottomSheetDialog.setContentView(inflate);
    View container = mBottomSheetDialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);
    final BottomSheetBehavior containerBehaviour = BottomSheetBehavior.from(container);
    containerBehaviour.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            Log.d(TAG, "onStateChanged: newState === " + newState);
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                mBottomSheetDialog.dismiss();
                containerBehaviour.setState(BottomSheetBehavior.STATE_COLLAPSED);
            } else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                //强制修改弹出高度为屏幕高度的0.9倍,不做此操作仅仅有CollapSed/Expand两种,就是0.5和1倍展开的效果
                containerBehaviour.setPeekHeight((int) (0.9 * height));
            }
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            Log.d("BottomBahaviour", "onSlide: slideOffset====" + slideOffset);
            if (slideOffset == 1.0) {
                mLeftIcon.setImageResource(R.drawable.back);

// containerBehaviour.setPeekHeight(height + getStatusBarHeight());
//修改状态栏
mBottomSheetDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mBottomSheetDialog.getWindow().setStatusBarColor(getResources().getColor(android.R.color.transparent));
try {
//修改魅族系统状态栏字体颜色
WindowManager.LayoutParams lp = mBottomSheetDialog.getWindow().getAttributes();
Field darkFlag = WindowManager.LayoutParams.class
.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class
.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
value |= bit;

                        meizuFlags.setInt(lp, value);
                        mBottomSheetDialog.getWindow().setAttributes(lp);

                    } catch (Exception e) {

                    }
                }
            } else {

                mLeftIcon.setImageResource(R.drawable.icon_delete);
            }
        }
    });

    btnShowDialog.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (!mBottomSheetDialog.isShowing()) {
                containerBehaviour.setPeekHeight((int) (0.9 * height));
                mBottomSheetDialog.show();
            } else {
                mBottomSheetDialog.dismiss();
            }
        }
    });

class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(BottomActivity.this).inflate(R.layout.layout_item, parent, false));
}

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mTvTip.setText(mDatas.get(position));
    }

    @Override
    public int getItemCount() {
        return mDatas == null && mDatas.size() < 0 ? 0 : mDatas.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        TextView mTvTip;

        public ViewHolder(View itemView) {
            super(itemView);
            mTvTip = (TextView) itemView.findViewById(R.id.tv_tips);
        }
    }
}
通过以上简单的错作即可实现我们想要的效果:

![pullSheet](http://upload-images.jianshu.io/upload_images/2605454-a1bcc209a0eba14f.gif?imageMogr2/auto-orient/strip)
这是在模拟器上运行的结果,在魅族手机呢?

![meizu](http://upload-images.jianshu.io/upload_images/2605454-ee040385cd582da2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
就这么简单即可完美实现效果。
#####总结
通过对Behaviour的学习很多看起来以前很难的效果我们都可以轻松实现。如果你发现上面有任何错漏,麻烦留言指出,同时我也会进行自我完善。
#####参考文章
[白底黑字!Android浅色状态栏黑色字体模式](http://www.jianshu.com/p/7f5a9969be53)
[Material Design系列](http://blog.csdn.net/yanzhenjie1003/article/details/52205665)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,999评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,102评论 1 302
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,709评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,439评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,846评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,881评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,062评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,783评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,517评论 1 248
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,762评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,241评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,236评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,145评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,941评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,965评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,802评论 2 275

推荐阅读更多精彩内容