Android5.0 Material design
来源:互联网 发布:淘宝店铺如何免费推广 编辑:程序博客网 时间:2024/06/11 11:37
在界面开发过程中,我们经常遇到子控件的移动到某一阶段,引起父控件或者其他控件产生动态效果;
在android 5.0 的Material design设计中,就为我们封装了一套这样的接口,即 NestedScrollingParent 和 NestedScrollingChild;
原理比较简单,当子控件需要滑动的时候,即调用startNestedScroll方法,在滑动之前,可以调用dispatchNestedPreScroll方法,来告诉父view是否需要滑动;
那么子view和父view是如果做到沟通的尼,这就需要第三个类来帮忙了 —- NestedScrollingChildHelper
下面的代码实现了 向左边滑动文字,当文字超过边界的时候, 图片收缩
package com.migu.hwj.component;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.support.v4.view.NestedScrollingChild;import android.support.v4.view.NestedScrollingChildHelper;import android.support.v4.view.NestedScrollingParent;import android.support.v4.view.NestedScrollingParentHelper;import android.support.v4.view.ViewCompat;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;import com.migu.hwj.as.leanring.R;import com.migu.hwj.util.MyLog;/* * 演示Android5.0中Material design设计总新增的一些控件和Api * * 同时这个类也演示了在XML中如何使用内部类,即在xml中使用内部类有两个注意的地方 * 1: 内部类是static的,public private没关系 * 2:在xml中控件需要使用view这样的标签,并以class标签描述类的完整路径,以$链接内部类 * * 参考:http://blog.csdn.net/gorgle/article/details/51428515 *//* * NestedScrolling机制 * 作用: 让父View和子View在滚动式进行配合,实现诸如子view滑动一定距离,父view是如何滑动的效果等等 * 主要接口 * NestedScrollingChild * NestedScrollingParent * 帮助类 * NestedScrollingChildHelper * NestedScrollingParentHelper * * 子view一般继承NestedScrollingChild接口作为动作的发起者, 父view一般继承NestedScrollingParent作用动作的响应者 * 正因为这种关系,因此当继承NestedScrollingChild接口的子view一些方法触发的时候,继承NestedScrollingParent的父view的一些方法也会被回调 * * 例如: * 子view的startNestedScroll会触发父view的onStartNestedScroll * */public class KitkatActivity extends Activity { private KitKatNestedScrollingParent mKitKatNestedScrollingParent; private LinearLayout.LayoutParams mKitNetedParentParams; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_nested_scrolling); } /* * Android5.0中Material design设计中配合子view滑动的父控件 */ public static class KitKatNestedScrollingParent extends LinearLayout implements NestedScrollingParent { private NestedScrollingParentHelper mNestedScrollingParentHelper; public KitKatNestedScrollingParent(Context context) { super(context); init(); } public KitKatNestedScrollingParent(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { mNestedScrollingParentHelper = new NestedScrollingParentHelper(this); } //因为实现NestedScrollingParent接口,而实现的方法 /** * 回调开始滑动 该方法决定了当前控件是否能接收到其内部View滑动时的参数 * * @param child 该父VIew 的子View * @param target 支持嵌套滑动的 VIew * @param nestedScrollAxes 滑动方向 * @return 是否支持 嵌套滑动 */ @Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { MyLog.logD("KitKatNestedScrollingParent onStartNestedScroll"); if (target instanceof KitKatNestedScrollingChild) { return true; } return false; } //因为实现NestedScrollingParent接口,而实现的方法 @Override public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes) { MyLog.logD("KitKatNestedScrollingParent onNestedScrollAccepted"); mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, nestedScrollAxes); } //因为实现NestedScrollingParent接口,而实现的方法 @Override public void onStopNestedScroll(View target) { MyLog.logD("KitKatNestedScrollingParent onStopNestedScroll"); mNestedScrollingParentHelper.onStopNestedScroll(target); } //因为实现NestedScrollingParent接口,而实现的方法 @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { MyLog.logD("KitKatNestedScrollingParent onNestedScroll"); } //因为实现NestedScrollingParent接口,而实现的方法 /* * 该方法的会传入内部View移动的dx,dy 前3个为输入参数,最后一个是输出参数 * consumed : The horizontal and vertical scroll distance consumed by this parent * 向上滑动 dy > 0, dx应该等于0(如果X坐标没有发生变化) * 向下滑动 dy < 0, dx应该等于0(如果X坐标没有发生变化) * 向左滑动 dx > 0, dy应该等于0(如果y坐标没有发生变化) * 向右滑动 dx < 0, dy应该等于0(如果y坐标没有发生变化) * * @param target View that initiated the nested scroll * @param dx Horizontal scroll distance in pixels * @param dy Vertical scroll distance in pixels * @param consumed Output. The horizontal and vertical scroll distance consumed by this parent */ @Override public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { MyLog.logD("KitKatNestedScrollingParent onNestedPreScroll dx " + dx); if (dx > 0) { scrollBy(dx,0);//滚动 consumed[0] = dx;//告诉child我消费了多少 } } //因为实现NestedScrollingParent接口,而实现的方法 /* * 捕获对内部View的fling事件,如果return true则表示拦截掉内部View的事件 */ @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { MyLog.logD("KitKatNestedScrollingParent onNestedFling"); return false; } //因为实现NestedScrollingParent接口,而实现的方法 @Override public boolean onNestedPreFling(View target, float velocityX, float velocityY) { MyLog.logD("KitKatNestedScrollingParent onNestedPreFling"); return false; } //因为实现NestedScrollingParent接口,而实现的方法 @Override public int getNestedScrollAxes() { MyLog.logD("KitKatNestedScrollingParent getNestedScrollAxes"); return mNestedScrollingParentHelper.getNestedScrollAxes(); } //scrollBy内部会调用scrollTo @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); } } /* * Android5.0中Material design设计中子view控件 */ public static class KitKatNestedScrollingChild extends LinearLayout implements NestedScrollingChild { //NestedScrolling帮助类,这个类似ontouch里面使用了手势识别帮助类 private NestedScrollingChildHelper mNestedScrollingChildHelper; //上一次水平滑动距离 private int lastX; private final int[] offset = new int[2]; //偏移量 private final int[] consumed = new int[2]; //消费 //子view宽 private int childWidth; public KitKatNestedScrollingChild(Context context) { super(context); } public KitKatNestedScrollingChild(Context context, AttributeSet attrs) { super(context, attrs); } /** * 设置嵌套滑动是否可用 * * @param enabled 参数enabled:true表示view使用嵌套滚动,false表示禁用. */ @Override public void setNestedScrollingEnabled(boolean enabled) { MyLog.logD("KitKatNestedScrollingChild getNestedScrollAxes"); getScrollingChildHelper().setNestedScrollingEnabled(enabled); } /** * 嵌套滑动是否可用 * * @return */ @Override public boolean isNestedScrollingEnabled() { MyLog.logD("KitKatNestedScrollingChild isNestedScrollingEnabled"); return getScrollingChildHelper().isNestedScrollingEnabled(); } /** * 开始嵌套滑动, * * @param axes 表示方向 有一下两种值 * ViewCompat.SCROLL_AXIS_HORIZONTAL 横向哈东 * ViewCompat.SCROLL_AXIS_VERTICAL 纵向滑动 * <p> * 返回值:true表示本次滚动支持嵌套滚动,false不支持 */ @Override public boolean startNestedScroll(int axes) { MyLog.logD("KitKatNestedScrollingChild startNestedScroll"); return getScrollingChildHelper().startNestedScroll(axes); } @Override public void stopNestedScroll() { MyLog.logD("KitKatNestedScrollingChild stopNestedScroll"); getScrollingChildHelper().stopNestedScroll(); } /** * 是否有父View 支持 嵌套滑动, 会一层层的网上寻找父View * * @return */ @Override public boolean hasNestedScrollingParent() { MyLog.logD("KitKatNestedScrollingChild hasNestedScrollingParent"); return getScrollingChildHelper().hasNestedScrollingParent(); } /** * 在处理滑动之后 调用 * * @param dxConsumed 表示view消费了x方向的距离长度 * @param dyConsumed 表示view消费了y方向的距离长度 * @param dxUnconsumed 表示滚动产生的x滚动距离还剩下多少没有消费 * @param dyUnconsumed 表示滚动产生的y滚动距离还剩下多少没有消费 * @param offsetInWindow 表示剩下的距离dxUnconsumed和dyUnconsumed使得view在父布局中的位置偏移了多少 * @return */ @Override public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { MyLog.logD("KitKatNestedScrollingChild dispatchNestedScroll"); return getScrollingChildHelper().dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow); } /** * 一般在滑动之前调用, 在ontouch 中计算出滑动距离, 然后调用该方法, 就给支持的嵌套的父View 处理滑动事件 * * @param dx x 轴上滑动的距离, 相对于上一次事件, 不是相对于 down事件的 那个距离 * @param dy y 轴上滑动的距离 * @param consumed 表示父布局消费的距离 一个数组, 可以传 一个空的 数组, 表示 x 方向 或 y 方向的事件 是否有被消费 consumed[0]表示x方向,consumed[1]表示y方向 * @param offsetInWindow 支持嵌套滑动到额父View 消费 滑动事件后 导致 本 View 的移动距离 * @return 支持的嵌套的父View 是否处理了 滑动事件 */ @Override public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { MyLog.logD("KitKatNestedScrollingChild dispatchNestedPreScroll"); return getScrollingChildHelper().dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow); } /** * @param velocityX x 轴上的滑动速度 * @param velocityY y 轴上的滑动速度 * @param consumed 是否被消费 * @return */ @Override public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { MyLog.logD("KitKatNestedScrollingChild dispatchNestedFling"); return getScrollingChildHelper().dispatchNestedFling(velocityX, velocityY, consumed); } /** * @param velocityX x 轴上的滑动速度 * @param velocityY y 轴上的滑动速度 * @return */ @Override public boolean dispatchNestedPreFling(float velocityX, float velocityY) { MyLog.logD("KitKatNestedScrollingChild dispatchNestedPreFling"); return getScrollingChildHelper().dispatchNestedPreFling(velocityX, velocityY); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); childWidth = this.getMeasuredWidth(); MyLog.logD("KitKatNestedScrollingChild onMeasure childWidth " + childWidth); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { //按下 case MotionEvent.ACTION_DOWN: lastX = (int) event.getRawX(); break; //移动 case MotionEvent.ACTION_MOVE: int x = (int) (event.getRawX()); int dx = x - lastX; lastX = x; scrollBy(-dx, 0); break; } return true; } //限制滚动范围 @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); //当超出内容显示的时候,通知父控制收放imageview MyLog.logD("KitKatNestedScrollingChild scrollTo x " + x + " lastX " + lastX); //向左滑 if(x >= childWidth && x > 0){ //startNestedScroll开始滑动 dispatchNestedPreScroll 通知父控件滑动 startNestedScroll(ViewCompat.SCROLL_AXIS_HORIZONTAL); dispatchNestedPreScroll(lastX, 0, consumed, offset); } } //初始化helper对象 private NestedScrollingChildHelper getScrollingChildHelper() { if (mNestedScrollingChildHelper == null) { mNestedScrollingChildHelper = new NestedScrollingChildHelper(this); mNestedScrollingChildHelper.setNestedScrollingEnabled(true); } return mNestedScrollingChildHelper; } }}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="match_parent" > <view class="com.migu.hwj.component.KitkatActivity$KitKatNestedScrollingParent" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:orientation="horizontal">h <ImageView android:layout_width="wrap_content" android:layout_height="match_parent" android:src="@mipmap/ic_launcher"/> <view class="com.migu.hwj.component.KitkatActivity$KitKatNestedScrollingChild" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="向左滑动可以收缩左边的图片" android:gravity="center" android:textColor="#f0f" android:textSize="20sp"/> </view> --> </view></LinearLayout>
package com.migu.hwj.util;import android.util.Log;public class MyLog{ private static boolean mOpenLog = true; private static String mTag = "hwj"; public static void setTag(String tag){ mTag = tag; } public static void logD(String message){ if(mOpenLog){ Log.d(mTag,message); } }}
阅读全文
0 0
- Android5.0 Material design
- android5.0 Material Design学习
- android5.0的Material Design
- Android5.0-Material Design(done)
- android5.0:Material Design简介
- Android5.0新特性-Material Design
- Android5.X (一) : Material Design
- Android5.0新特性 -- Material Design材料设计(1)
- Android5.0新特性——Material Design简介
- Material Design设计(Android5.0新特性)
- Android5.X (四) : Material Design-动画效果
- Material Design设计语言(Android5.X)
- Android5.X之Material Design与主题
- Android5.0 Material Desgin 设计
- Android5.X (二) : Material Design:对图像的操作!
- Material Design(Android6.0)
- Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决
- Material Design
- 【枚举算法】全素组
- 6.13 if语句
- 理解Threadlocal
- 高程笔记-总结从javascript内存空间引出的1mol多问题
- linux 串口用户模式改为root模式
- Android5.0 Material design
- Noip2017 Day2T1 cheese
- Eclipse设置、调优、使用
- 世界坐标系与像素坐标系的点互相转换
- KAZE匹配算法源码
- C语言面向对象编程之六:配置文件解析
- linux ubuntu环境下安装jdk(要求网络畅通有一定网速)
- Linux命令行
- shell 脚本编程学习(三) 条件控制,循环控制