【Android自定义控件】布局悬停在顶部
2015-12-15 17:55
387 查看
语言表达能力有限,我们先来看下效果:
![](http://img.blog.csdn.net/20151215165908716?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
好了,如果你明白了我说的效果,那就继续往下看吧!
思路是这样的:
首先,我们要自定义一个HoverScrollView,继承ScrollView,通过接口把onScrollChanged(int l, int t, int oldl, int oldt)方法里scrollview移动的Top值暴露出来,然后在Activity根据scrollview的Top值以及需要悬浮的布局mHoverLayoutTop距离上边缘的size,通过两者的比较,当Top的值大于等于size时把mHoverLayoutTop设置VISIBLE以及INVISIBLE。
这里有必要先介绍下Left,Top,Right,Bottom这几个值的含义:
![](http://img.blog.csdn.net/20151215172600091?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
下面是暴露出scrollview滑动时的Top值的代码,这里很明显我们开个接口
开接口一般我们记住以下几个步骤:
创建接口,声明接口带参数的抽象方法,声明一个接口类型的引用来指向一个实现给接口的对象,对这个引用赋值,最后别忘记给接口传递的参数赋值(去调用接口的方法)。
下面是自定义HoverScrollView的代码:
然后我们来看下布局的代码,这里使用FrameLayout,可以看到悬停的布局位于FrameLayout的上层,这里我们把悬停的布局先gone掉,代码如下:
在Activity里面我们可以通过计算悬停布局上边布局的累加高度取得size,或者如果知道准确的高度可以直接通过getResources().getDimensionPixelSize(R.dimen.xxx)取得,这里还应该知道,控件获取高度的方法getHeight()在onCreate()方法和onResume()方法里调用都是为0的,这是因为此时布局还没有渲染完成,我们写个轮询线程来获取渲染完成后的控件高度,代码如下:
本博客部分思路来自夏安明的博客,向他致谢!
好了,如果你明白了我说的效果,那就继续往下看吧!
思路是这样的:
首先,我们要自定义一个HoverScrollView,继承ScrollView,通过接口把onScrollChanged(int l, int t, int oldl, int oldt)方法里scrollview移动的Top值暴露出来,然后在Activity根据scrollview的Top值以及需要悬浮的布局mHoverLayoutTop距离上边缘的size,通过两者的比较,当Top的值大于等于size时把mHoverLayoutTop设置VISIBLE以及INVISIBLE。
这里有必要先介绍下Left,Top,Right,Bottom这几个值的含义:
下面是暴露出scrollview滑动时的Top值的代码,这里很明显我们开个接口
开接口一般我们记住以下几个步骤:
创建接口,声明接口带参数的抽象方法,声明一个接口类型的引用来指向一个实现给接口的对象,对这个引用赋值,最后别忘记给接口传递的参数赋值(去调用接口的方法)。
下面是自定义HoverScrollView的代码:
public class HoverScrollView extends ScrollView { private OnScrollListener onScrollListener; public interface OnScrollListener{ public void onScroll(int scrollY); }; public HoverScrollView(Context context) { super(context, null, 0); // TODO Auto-generated constructor stub } public HoverScrollView(Context context, AttributeSet attrs) { super(context, attrs, 0); // TODO Auto-generated constructor stub } public HoverScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public void setOnScrollListener(OnScrollListener onScrollListener){ this.onScrollListener = onScrollListener; } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { // TODO Auto-generated method stub super.onScrollChanged(l, t, oldl, oldt); if(onScrollListener!=null){ onScrollListener.onScroll(t); } } }
然后我们来看下布局的代码,这里使用FrameLayout,可以看到悬停的布局位于FrameLayout的上层,这里我们把悬停的布局先gone掉,代码如下:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" > <com.mw.yejg.andtest.view.HoverScrollView android:id="@+id/hsv" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/iv_head" android:layout_width="match_parent" android:layout_height="@dimen/y100" android:background="@drawable/ic_launcher" /> <LinearLayout android:id="@+id/layout_hover_scroll" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#aaaaaa" android:orientation="horizontal" > <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="button1" /> <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="button2" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="@dimen/y100" android:gravity="center" android:text="text" /> <TextView android:layout_width="match_parent" android:layout_height="@dimen/y100" android:background="#dddddd" android:gravity="center" android:text="text" /> <TextView android:layout_width="match_parent" android:layout_height="@dimen/y100" android:gravity="center" android:text="text" /> <TextView android:layout_width="match_parent" android:layout_height="@dimen/y100" android:background="#dddddd" android:gravity="center" android:text="text" /> <TextView android:layout_width="match_parent" android:layout_height="@dimen/y100" android:gravity="center" android:text="text" /> <TextView android:layout_width="match_parent" android:layout_height="@dimen/y100" android:background="#dddddd" android:gravity="center" android:text="text" /> </LinearLayout> </com.mw.yejg.andtest.view.HoverScrollView> <LinearLayout android:id="@+id/layout_hover_top" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#aaaaaa" android:orientation="horizontal" android:visibility="gone" > <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="button1" /> <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="button2" /> </LinearLayout> </FrameLayout>
在Activity里面我们可以通过计算悬停布局上边布局的累加高度取得size,或者如果知道准确的高度可以直接通过getResources().getDimensionPixelSize(R.dimen.xxx)取得,这里还应该知道,控件获取高度的方法getHeight()在onCreate()方法和onResume()方法里调用都是为0的,这是因为此时布局还没有渲染完成,我们写个轮询线程来获取渲染完成后的控件高度,代码如下:
public class TestHoverAct extends Activity implements OnScrollListener { private HoverScrollView mHsv; private LinearLayout mHoverLayoutTop; private int size; private ImageView mIvHead; // 开个轮询线程,循环直到对size赋上非0的值 private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { if (msg.what == 1) { // 顶部高度为0时,表示布局未完成,继续轮询 if (mIvHead.getHeight() == 0) { mHandler.sendEmptyMessageDelayed(1, 10); return; } size = mIvHead.getHeight(); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_test_hover); mHsv = (HoverScrollView) findViewById(R.id.hsv); mIvHead = (ImageView) findViewById(R.id.iv_head); mHoverLayoutTop = (LinearLayout) findViewById(R.id.layout_hover_top); mHsv.setOnScrollListener(this); // 如果知道准确的高度,可以直接取得 // size = getResources().getDimensionPixelSize(R.dimen.y100); // 10毫秒循环判断 mHandler.sendEmptyMessageDelayed(1, 10); } @Override public void onScroll(int scrollY) { Log.e("scroll::", "size::" + size + ", scrollY::" + scrollY); if (scrollY >= size) { mHoverLayoutTop.setVisibility(View.VISIBLE); } else { mHoverLayoutTop.setVisibility(View.INVISIBLE); } } }
本博客部分思路来自夏安明的博客,向他致谢!
相关文章推荐
- __android_log_vprint可变参数打印日志
- ImageView的ScaleType属性
- android-view animation
- Android-->实现可滑动删除的Layout
- Android X轴Y轴Z轴旋转
- Atitit.播放系统规划新版本 and 最近版本回顾 v3 pbf.doc 1 版本11 (ing)41.1 规划h5本地缓存系列 41.2 Android版本app41.3 双类别系统,
- imageswitcher+gallay实现相册功能
- android 常用命令
- Junit单元测试问题 junit.framework.AssertionFailedError: Method "test" not found at android.test.AndroidTes
- Android中的布局优化方法
- android接收不到广播的可能原因
- Android四大组件之service
- 《Android群英传》读书笔记(2)第四章:ListView常用优化技巧
- Android字符串分隔之split
- xmpp/aSmack源码分析(基于android客户端)
- Android获取系统服务
- Android开发经验总结
- ButterKnife + ButterKnife Zelezny(Android Studio)
- AndroidStudio 编译异常java.lang.OutOfMemoryError: GC overhead limit exceeded
- Android用SoundPool播放音效