码迷,mamicode.com
首页 > 其他好文 > 详细

自定义ScrollView,实现导航条悬浮置顶

时间:2016-07-19 11:00:11      阅读:349      评论:0      收藏:0      [点我收藏+]

标签:

Android ScrollView向上滑动控件顶部悬浮效果实现
* 导航栏实现悬浮置顶效果(顶部图片隐藏,下面的单选框导航悬浮)
【上滑停靠顶端的悬浮框】里的实现方法是使用两个控件,滑动时,监听ScrollView的滚动Y值,
* 从而通过对两个控件的显示隐藏来实现控件的顶部悬浮。但是实际应用场景中,
* 有可能需要悬浮的控件里面的内容是比较多的,如果通过显示隐藏的方式来实现的话,
* 操作控件里的内容时,需要重复定义两套变量,对控件里的内容进行修改时也是要操作再次,非常麻烦。
本文的方法是通过addViewremoveView来实现的


	当外面嵌套一层ScrollView后,就能做上下或左右滑动,但能滑动多少系统不知道,
* 	这时就需要你给计算出一个滑动区域给ScrollView


知识点:

1、当ScrollView垂直滚动视图中嵌套ListView时,ListView必须重写onMeasure方法,返回高度和大小,否则,只会显示一行布局!!!


2、滑动事件会有冲突:重写
onInterceptTouchEvent方法(或者其他事件的方法),根据情况获得事件!



首先继承ScrollView类:

public class HoveringScrollview extends ScrollView {
    private OnScrollListener onScrollListener;
    /**
     * 主要是用在用户手指离开本view,本view还在继续滑动,我们用来保存Y的距离,然后做比较
     */
    private int lastScrollY;

    public HoveringScrollview(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    /**
     * 设置滚动接口
     *
     * @param onScrollListener
     */
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

    /**
     * 用于用户手指离开MyScrollView的时候获取MyScrollView滚动的Y距离,然后回调给onScroll方法中
     */
    private Handler handler = new Handler() {

        public void handleMessage(android.os.Message msg) {
            int scrollY = HoveringScrollview.this.getScrollY();

            // 此时的距离和记录下的距离不相等,在隔6毫秒给handler发送消息?
            if (lastScrollY != scrollY) {
                lastScrollY = scrollY;
                handler.sendMessageDelayed(handler.obtainMessage(), 6);
            }
            if (onScrollListener != null) {
                onScrollListener.onScroll(scrollY);
            }

        };

    };

    /**
     * 重写onTouchEvent, 当用户的手在HoveringScrollview上面的时候,
     * 直接将HoveringScrollview滑动的Y方向距离回调给onScroll方法中,当用户抬起手的时候,
     * HoveringScrollview可能还在滑动,所以当用户抬起手我们隔6毫秒给handler发送消息,在handler处理
     * HoveringScrollview滑动的距离
     */
    public boolean onTouchEvent(MotionEvent ev) {
        if (onScrollListener != null) {
            onScrollListener.onScroll(lastScrollY = this.getScrollY());
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP://用户把手拿开
                //发送信息回去
                handler.sendMessageDelayed(handler.obtainMessage(), 20);
                break;
        }
        return super.onTouchEvent(ev);
    };

    /**
     * 滚动的回调接口
     */
    public interface OnScrollListener {
        /**
         * 回调方法, 返回本view滑动的Y(上下)方向距离
         */
        public void onScroll(int scrollY);
    }

}



在Activity(Fragment)中:

重要方法:

    //获得组件的大小(Fragment中)
        ViewTreeObserver vto=rlayout.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                searchLayoutTop=rlayout.getHeight();
            }
        });

 @Override//当hasFocus == true,表示加载完成    Activity中才有该方法
    public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            searchLayoutTop = rlayout.getBottom();// 获取searchLayout的顶部位置
        }
    }


Fragment中的JAVA代码:

public class Item_Fragment extends Fragment implements View.OnClickListener, HoveringScrollview.OnScrollListener {
    private HoveringScrollview hoveringScrollview;
    private int searchLayoutTop;

    ViewTop viewtop;
    LinearLayout hoveringLayout;
    LinearLayout search01, search02;
    RelativeLayout rlayout;
    RadioGroup radioGroup;
    FrameLayout layout;



    private ItemZI_Fragment1 fragment1;
    private ItemZI_Fragment2 fragment2;
    private ItemZI_Fragment3 fragment3,fragment4;


    private Bundle bundle;
    private Fragment currentFragment;//记录当前显示的碎片对象


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.item_fragment, container, false);
        initView(view);
        return view;
    }

    private void initView(View view) {
        view.findViewById(R.id.item_msg).setOnClickListener(this);
        view.findViewById(R.id.item_camera).setOnClickListener(this);

        //悬浮条线性布局(固定大小的布局)[首先嵌套在2号布局里面]
        hoveringLayout = (LinearLayout) view.findViewById(R.id.hoveringLayout);

        hoveringScrollview = (HoveringScrollview) view.findViewById(R.id.hoveringScrollview);//滚动视图
        search01 = (LinearLayout) view.findViewById(R.id.search01);//最下面的3号布局

        search02 = (LinearLayout) view.findViewById(R.id.search02);//2号布局

        rlayout = (RelativeLayout) view.findViewById(R.id.rlayout);//1号布局(顶部的内容)

        layout= (FrameLayout) view.findViewById(R.id.layout);

        radioGroup= (RadioGroup) view.findViewById(R.id.item_list_group);

        viewtop= (ViewTop) view.findViewById(R.id.viewtop);

        viewtop.setOnLienter(new ViewTop.OnListeren() {
            @Override
            public String[] getURL() {
                return URLClass.ItemTops;
            }
        });

        viewtop.setData(true);

        hoveringScrollview.setOnScrollListener(this);// set Listener  设置监听

        for (int i = 0; i <radioGroup.getChildCount() ; i++) {
            //遍历单选组里面的控件,设置点击事件
            ((RadioButton)radioGroup.getChildAt(i)).setOnClickListener(this);
        }

        //获取碎片管理器对象, //开启事物,获得操作碎片的对象
        FragmentTransaction transaction =getActivity().getSupportFragmentManager().beginTransaction();

        fragment1 = new ItemZI_Fragment1();
        bundle = new Bundle();
        bundle.putString("url",URLClass.ItemURL1);
        fragment1.setArguments(bundle);

        currentFragment = fragment1;//记录当前的碎片
        transaction.add(R.id.layout, fragment1);//添加帧布局和碎片对象
        transaction.commit();//提交事物

        //获得组件的大小(Fragment中)
        ViewTreeObserver vto=rlayout.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                searchLayoutTop=rlayout.getHeight();
            }
        });

    }

  /*
    @Override//当hasFocus == true,表示加载完成    Activity中才有该方法
    public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            searchLayoutTop = rlayout.getBottom();// 获取searchLayout的顶部位置
        }
    }
*/


    @Override//实现的滚动方法
    public void onScroll(int scrollY) {
        // TODO Auto-generated method stub
        if (scrollY >= searchLayoutTop) {
            if (hoveringLayout.getParent() != search01) {
                search02.removeView(hoveringLayout);  //2号布局删除  悬浮体布局
                search01.addView(hoveringLayout);   //3号底层布局添加  悬浮体布局
            }
        } else {
            if (hoveringLayout.getParent() != search02) {
                search01.removeView(hoveringLayout);   //3号底层布局删除   悬浮体布局
                search02.addView(hoveringLayout);    //2号布局添加   悬浮体布局
            }
        }
    }

    private int counnt;
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.item_list_b1:
                counnt=0;
                showFragment(1);
                break;
            case R.id.item_list_b2:
                counnt=1;
                showFragment(2);
                break;
            case R.id.item_list_b3:
                counnt=2;
                showFragment(3);
                break;
            case R.id.item_list_b4:
                counnt=3;
                showFragment(4);
                break;
        }

        for (int i = 0; i <radioGroup.getChildCount() ; i++) {

            RadioButton button= (RadioButton) radioGroup.getChildAt(i);
            if(i==counnt){
                button.setTextColor(getResources().getColor(R.color.main_text_yes));
                continue;
            }
            button.setTextColor(getResources().getColor(R.color.main_text_no));
        }
    }

    //显示碎片对象,隐藏当前的碎片对象
    private void showFragment(int index) {
        //碎片操作对象,不能定义全局的,负责秒报错
        FragmentTransaction transaction =getActivity().getSupportFragmentManager().beginTransaction();

        if (index == 1) {//热门碎片
            if (fragment1 == null) {
                fragment1 = new ItemZI_Fragment1();
                bundle = new Bundle();
                bundle.putString("url",URLClass.ItemURL1);
                fragment1.setArguments(bundle);
            }
            if (fragment1.isAdded()) {//如果碎片对象存在
                transaction.show(fragment1);//显示该碎片
                transaction.hide(currentFragment);//隐藏当前碎片(前一个)
            } else {//如果碎片对象不存在
                transaction.add(R.id.layout, fragment1);//添加碎片
                transaction.hide(currentFragment);//隐藏当前的碎片
            }
            transaction.commit();//提交事件
            currentFragment = fragment1;//记录当前显示的碎片

        } else if (index == 2) {//关注碎片
            if (fragment2 == null) {
                fragment2 = new ItemZI_Fragment2();
                bundle = new Bundle();
                bundle.putString("url",URLClass.ItemURL2);
                fragment2.setArguments(bundle);
            }
            if (fragment2.isAdded()) {//如果碎片对象存在
                transaction.show(fragment2);//显示该碎片
                transaction.hide(currentFragment);//隐藏当前碎片(前一个)
            } else {//如果碎片对象不存在
                transaction.add(R.id.layout, fragment2);//添加碎片
                transaction.hide(currentFragment);//隐藏当前的碎片
            }
            transaction.commit();//提交事件
            currentFragment = fragment2;//记录当前显示的碎片

        } else if (index == 3) {//红人碎片
            if (fragment3 == null) {
                fragment3 = new ItemZI_Fragment3();
                bundle = new Bundle();
                bundle.putString("url",URLClass.ItemURL3);
                fragment3.setArguments(bundle);
            }
            if (fragment3.isAdded()) {//如果碎片对象存在
                transaction.show(fragment3);//显示该碎片
                transaction.hide(currentFragment);//隐藏当前碎片(前一个)
            } else {//如果碎片对象不存在
                transaction.add(R.id.layout, fragment3);//添加碎片
                transaction.hide(currentFragment);//隐藏当前的碎片
            }
            transaction.commit();//提交事件
            currentFragment = fragment3;//记录当前显示的碎片

        } else if (index == 4) {//线下店碎片
            if (fragment4 == null) {
                fragment4 = new ItemZI_Fragment3();
                bundle = new Bundle();
                bundle.putString("url",URLClass.ItemURL4);
                fragment4.setArguments(bundle);
            }
            if (fragment4.isAdded()) {//如果碎片对象存在
                transaction.show(fragment4);//显示该碎片
                transaction.hide(currentFragment);//隐藏当前碎片(前一个)
            } else {//如果碎片对象不存在
                transaction.add(R.id.layout, fragment4);//添加碎片
                transaction.hide(currentFragment);//隐藏当前的碎片
            }
            transaction.commit();//提交事件
            currentFragment = fragment4;//记录当前显示的碎片
        }

    }
}



XML布局:  顶部布局必须为相对布局,否则不会悬浮组件,会覆盖

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">

    <!-- 社区的碎片的布局,相对布局才有效果-->
    <android.support.v7.widget.Toolbar
        android:id="@+id/item_toolbar"
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <RelativeLayout
            android:layout_marginTop="8dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="100dp"
                android:gravity="center"
                android:layout_height="match_parent"
                android:layout_centerInParent="true"
                android:textSize="20sp"
                android:textColor="#181515"
                android:text="社区"
                />

            <ImageView
                android:id="@+id/item_msg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="20dp"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:background="@mipmap/button_head_massage"/>

            <ImageView
                android:id="@+id/item_camera"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="20dp"
                android:layout_toLeftOf="@id/item_msg"
                android:layout_centerVertical="true"
                android:background="@mipmap/button_head_camera"/>

        </RelativeLayout>

    </android.support.v7.widget.Toolbar>


    <com.android.starapp.view.HoveringScrollview
        android:id="@+id/hoveringScrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <RelativeLayout
                android:id="@+id/rlayout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal">

                <com.android.starapp.view.ViewTop
                    android:id="@+id/viewtop"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    />
            </RelativeLayout>

            <!-- 这个悬浮条必须是固定高度 -->
            <LinearLayout
                android:id="@+id/search02"
                android:layout_width="match_parent"
                android:layout_height="70dp">
                <LinearLayout
                    android:id="@+id/hoveringLayout"
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:background="#fff"
                    >
                    <RadioGroup
                        android:id="@+id/item_list_group"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:orientation="horizontal"
                        android:weightSum="4">

                        <RadioButton
                            android:id="@+id/item_list_b1"
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:button="@null"
                            android:checked="true"
                            android:drawableBottom="@drawable/match_toolbar_main"
                            android:gravity="center"
                            android:text="热门"
                            android:textColor="@color/main_text_yes" />

                        <RadioButton
                            android:id="@+id/item_list_b2"
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:button="@null"
                            android:drawableBottom="@drawable/match_toolbar_main"
                            android:gravity="center"
                            android:text="关注"
                            android:textColor="@color/main_text_no" />

                        <RadioButton
                            android:id="@+id/item_list_b3"
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:button="@null"
                            android:drawableBottom="@drawable/match_toolbar_main"
                            android:gravity="center"
                            android:text="红人"
                            android:textColor="@color/main_text_no" />

                        <RadioButton
                            android:id="@+id/item_list_b4"
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:button="@null"
                            android:drawableBottom="@drawable/match_toolbar_main"
                            android:gravity="center"
                            android:text="线下店"
                            android:textColor="@color/main_text_no" />

                    </RadioGroup>
                </LinearLayout>
            </LinearLayout>

            <FrameLayout
                android:id="@+id/layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                />
        </LinearLayout>
    </com.android.starapp.view.HoveringScrollview>

    <LinearLayout
        android:id="@+id/search01"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:orientation="vertical"></LinearLayout>

</RelativeLayout>


自定义ScrollView,实现导航条悬浮置顶

标签:

原文地址:http://blog.csdn.net/qq_34997963/article/details/51933055

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!