自定义控件 仿应用宝 管理界面的标题栏缩放效果
来源:互联网 发布:对人工智能社会的畅想 编辑:程序博客网 时间:2024/06/01 08:58
最近看到应用宝管理界面里面那个能缩能放的标题栏很有意思,所以自己尝试简单模仿下。
先上效果图:
实现原理:
在listview里面设置ontouch监听,判断滑动方向和蓝色区域的状态,如果蓝色区域状态是显示最大且滑动方向向上,那么缩小该区域,如果蓝色区域最小,且滑动方向向下,则放大该区域。如果区域既不最大 也不最小,那么即可放大也可缩小。
蓝色区域继承framelayout,小标题和大标题的visibile是相反设置的,也就是说只能显示一个标题。
结合代码:
开始做初始化:通过id获取两个标题栏View,并得到他们的高度和设置大标题View可见,小标题View不可见。这里需要注意一点:在绘制没有完成的情况下获取到的高度是0,那么就会出问题, 所以initData()函数要放在下面的地方执行。
http://stackoverflow.com/questions/11946424/getmeasuredheight-and-width-returning-0-after-measure
这个网址做了详细解释
这个网址做了详细解释
@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(bigHeaderView == null && smallHeaderView == null){ initData(); } }
private void initData() { int bigHeaderViewId= getResources().getIdentifier("big_header_view", "id", getContext().getPackageName()); int smallHeaderViewId = getResources().getIdentifier("small_header_view", "id", getContext().getPackageName());// System.out.println("bigHeaderViewId = " + bigHeaderViewId + " smallHeaderViewId = " + smallHeaderViewId); if (bigHeaderViewId != 0 && smallHeaderViewId != 0) { bigHeaderView = findViewById(bigHeaderViewId); smallHeaderView = findViewById(smallHeaderViewId); heightBV = bigHeaderView.getMeasuredHeight(); currentHeightBV = heightBV; heightSV = smallHeaderView.getMeasuredHeight();// System.out.println("heightBV = " + heightBV + " heightSV = " + heightSV); bigHeaderView.setVisibility(VISIBLE); smallHeaderView.setVisibility(INVISIBLE); state = BIG_HEADER_VIEW_STATE; } else { Log.e("Error Inform", "没有设置HeaderView Id"); } }
下面是改变蓝色区域大小的代码:
//根据滑动设置高度 public void setHeaderHeight(float dis) { int height = (int)(currentHeightBV + dis); if (height < heightSV) { height = heightSV; } else if (height > heightBV) { height = heightBV; } if (bigHeaderView != null && bigHeaderView.getLayoutParams() != null) { bigHeaderView.getLayoutParams().height = height; System.out.println("height = " + height + " currentHeight = " + currentHeightBV); //计算缩放比,有了缩放比,你就可以做很多其他事情,比如控制alpha变化,控制scale变化 //像有些标题栏是根据手势移动,来改变透明度的. float scalePercent = (height - heightSV)*1.0f / (heightBV - heightSV); setTextViewHeight(scalePercent); bigHeaderView.requestLayout(); } else { Log.e(TAG, "bigHeaderView = null"); } if(height <= heightSV){ smallHeaderView.setVisibility(VISIBLE); bigHeaderView.setVisibility(INVISIBLE); state = SMALL_HEADER_VIEW_STATE; } else { smallHeaderView.setVisibility(INVISIBLE); bigHeaderView.setVisibility(VISIBLE); if(height == heightBV) state = BIG_HEADER_VIEW_STATE; else state = MID_HEADER_VIEW_STATE; } }
为了体验更好,在蓝色区域缩放到2/3以内大小的时候,自动缩小直到最小。我的实现方式是通过线程来慢慢改变高度,详见代码,注释很详细
/** * 当位置大于heightSV 并且小于 heightBV*2/3的时候,执行平滑缩放 * 感觉自己用线程实现的平滑效果不是很好...... */ public void smoothSetHeaderHeight() { currentHeightBV = bigHeaderView.getHeight(); final int timeCount = 1*200; //0.2秒钟 从heightBV*2/3 缩放到 heightSV final float dis = -1 * (heightBV*2.0f/3.0f-heightSV)*1.0f/timeCount*10;// System.out.println("currentHeightBV = " + currentHeightBV); if(currentHeightBV > (heightBV*2 / 3) || currentHeightBV <= heightSV) { return; }// System.out.println("dis = " + dis); new Thread() { @Override public void run() { for (int i = 0; i < timeCount/10; i++) { final float sumDis = i*dis + dis; post(new Runnable() { public void run() { setHeaderHeight(sumDis); } }); try { sleep(10); //为了体验好点,慢慢缩放 } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); }
下面贴上recycleview的事件监听代码
View.OnTouchListener onTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int moveY = (int)event.getRawY(); //取得手指相对屏幕的Y坐标 if(event.getAction() == MotionEvent.ACTION_DOWN){ mDownY = event.getRawY(); //按下时候的坐标 } if(event.getAction() == MotionEvent.ACTION_MOVE){ int dis = (int)(moveY - mDownY); //移动距离// System.out.println("move distance = " + dis); int state = scrollerHeaderLayout.getState(); //当前滑动状态 //下滑时候 需要做如下操作 if(dis > 0 && !recycleView.canScrollVertically(-1) && (state == ScrollerHeaderLayout.SMALL_HEADER_VIEW_STATE || state == ScrollerHeaderLayout.MID_HEADER_VIEW_STATE)){// System.out.println("stateScrollerDir" + stateScrollerDir); /** * 这里逻辑是:如果你突然换方向移动,那么需要改变mDownY的坐标为"换方向的那个转折点"的Y标。 * 并初始化当前 scrollerHeaderLayout的高度。 */ if(stateScrollerDir < 0) { mDownY = moveY; scrollerHeaderLayout.initCurrentHeightBV(); } //改变移动状态 stateScrollerDir = 1; dis = (int)(moveY - mDownY); //重新计算距离 :可能换方向移动了,原来计算的距离不对了. scrollerHeaderLayout.setHeaderHeight(dis); //设置高度 return true; } //上滑 同下滑操作一样 if(dis < 0 && (state == ScrollerHeaderLayout.BIG_HEADER_VIEW_STATE || state == ScrollerHeaderLayout.MID_HEADER_VIEW_STATE)){ if(stateScrollerDir > 0) { mDownY = moveY; scrollerHeaderLayout.initCurrentHeightBV();// System.out.println("mDownY = " + mDownY); } stateScrollerDir = -1; dis = (int)(moveY - mDownY);// System.out.println("-1 dis = " + dis); scrollerHeaderLayout.setHeaderHeight(dis); return true; } mDownY = event.getRawY(); } if(event.getAction() == MotionEvent.ACTION_UP){ scrollerHeaderLayout.initCurrentHeightBV(); scrollerHeaderLayout.smoothSetHeaderHeight(); } return false; } };
总结:这里通过线程方式实现的自动缩放致最小高度,因为是匀速的,效果有点不太好...
0 0
- 自定义控件 仿应用宝 管理界面的标题栏缩放效果
- 自定义仿全民直播界面的悬停效果
- Android 仿Win8的metro的UI界面(点击缩放效果)
- 自定义控件:onDraw 方法实现仿 iOS 的开关效果
- Android 自定义控件 仿MX 播放器的SeekBar效果
- 自定义控件之DragLayout仿QQ界面
- Android自定义控件--仿 path 效果 ArcMenu
- 自定义控件 | 仿《最美有物》点赞效果
- Android综合Demo 仿Win8可拖拽界面 自定义控件 自定义spinner,自定义顶栏和副顶栏,内存管理
- Android应用界面无标题栏和全屏效果的两种实现方式
- Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用)
- 自定义窗口的玻璃效果(边框,标题栏...)
- 自定义窗口的玻璃效果(边框,标题栏...)
- Android 功能最强的自定义标题栏控件
- 安卓自定义简单的Title标题栏(仿iPhone样式)
- 利用Opengl仿写cocos2dx的旋转+缩放的效果
- 自定义ScrollView控件 -- 拉申时跟随缩放效果
- 自定义控件 标题栏
- Maven的三种关系:继承,聚合,依赖
- 亿级Web系统搭建:单机到分布式集群
- FC22 SSH open
- python入门2
- VirtualBox虚拟机网络设置(四种方式)
- 自定义控件 仿应用宝 管理界面的标题栏缩放效果
- 同样思路解决不同的问题,集大成者
- 魅族的品牌策略
- dom节点
- JAVA 学习关于 类
- 黑马程序员——Java语言基础:多线程
- C#委托(delegate)简单示例:在两个form之间传递数据
- XMPP协议
- 自定义控件其实很简单