ObservableScrollView+TabPageIndicator+fragment 实现顶部悬浮菜单效果

顶部悬浮是在scrollview中进行的。通过在scrollview添加空布局来实现。

直接上代码

/*
 * Copyright 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zhsq365.yuci.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * A custom ScrollView that can accept a scroll listener.
 */
public class ObservableScrollView extends ScrollView {
    private Callbacks mCallbacks;

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

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mCallbacks != null) {
            mCallbacks.onScrollChanged(t);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mCallbacks != null) {
            switch (ev.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    mCallbacks.onDownMotionEvent();
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    mCallbacks.onUpOrCancelMotionEvent();
                    break;
            }
        }
        return super.onTouchEvent(ev);
    }

    @Override
    public int computeVerticalScrollRange() {
        return super.computeVerticalScrollRange();
    }

    public void setCallbacks(Callbacks listener) {
        mCallbacks = listener;
    }

    public static interface Callbacks {
        public void onScrollChanged(int scrollY);
        public void onDownMotionEvent();
        public void onUpOrCancelMotionEvent();
    }
}
重写的scollview来监听滑动事件。

再上xml布局文件

<com.zhsq365.yuci.view.ObservableScrollView
            android:id="@+id/scroll_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/layout_title"
            android:scrollbars="none"
            android:fillViewport="true">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <LinearLayout
                    android:id="@+id/header"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@color/shop_bg_color"
                    android:orientation="vertical">

                    <RelativeLayout
                        android:id="@+id/layoutViewPager"
                        android:layout_width="match_parent"
                        android:layout_height="163dp">

                        <android.support.v4.view.ViewPager
                            android:id="@+id/LoopViewPager"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:background="@drawable/binder_view_default" />

                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_alignBottom="@+id/LoopViewPager"
                            android:layout_alignParentLeft="true"
                            android:orientation="vertical"
                            android:padding="8dp">

                            <LinearLayout
                                android:id="@+id/dot"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center_horizontal"
                                android:layout_marginTop="3dp"
                                android:orientation="horizontal"></LinearLayout>
                        </LinearLayout>
                    </RelativeLayout>

                    <!--此处重要-->
                    <View
                        android:id="@+id/placeholder"
                        android:layout_width="fill_parent"
                        android:layout_height="@dimen/min_height_textheader_materiallike" />
                    <com.zhsq365.yuci.view.ScrollByViewpager
                        android:id="@+id/viewPager"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1" />
                </LinearLayout>

                <com.zhsq365.yuci.widget.wheelview.viewpagerindicator.TabPageIndicator
                    android:id="@+id/tabPageIndicator"
                    android:layout_width="fill_parent"
                    android:layout_height="@dimen/min_height_textheader_materiallike"
                    android:background="#F3F3F3" />
            </FrameLayout>

        </com.zhsq365.yuci.view.ObservableScrollView>

布局文件中,placeholder和tabPage控件则为悬浮控件!

MainActivity中代码

1、首先实现observableScrollView.callback 接口

2、在activity中设置监听。更具计算高度,来控制悬浮框

mScrollview.setCallbacks(this);
        mScrollview.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        onScrollChanged(mScrollview.getScrollY());
                    }
                });
3、
public void onScrollChanged(int scrollY) {
        tabPageIndicator.setTranslationY(Math.max(placeholder.getTop(), scrollY));

    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个实现需要以下步骤: 1. 在布局文件中添加ViewPager2和TabLayout: ```xml <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabGravity="fill" app:tabMode="fixed" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在代码中初始化ViewPager2和TabLayout: ```java ViewPager2 viewPager = findViewById(R.id.view_pager); TabLayout tabLayout = findViewById(R.id.tab_layout); viewPager.setAdapter(new MyPagerAdapter(this)); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText("Tab " + (position + 1)) ).attach(); ``` 3. 创建PagerAdapter,用于管理Fragment: ```java public class MyPagerAdapter extends FragmentStateAdapter { public MyPagerAdapter(FragmentActivity fa) { super(fa); } @Override public Fragment createFragment(int position) { return new MyFragment(position + 1); } @Override public int getItemCount() { return 3; } } ``` 4. 创建Fragment,用于显示RecyclerView: ```java public class MyFragment extends Fragment { private int mTabNumber; public MyFragment(int tabNumber) { mTabNumber = tabNumber; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_my, container, false); RecyclerView recyclerView = rootView.findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setAdapter(new MyRecyclerViewAdapter(mTabNumber)); return rootView; } } ``` 5. 创建RecyclerViewAdapter,用于显示数据: ```java public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> { private int mTabNumber; public MyRecyclerViewAdapter(int tabNumber) { mTabNumber = tabNumber; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_my, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.mTextView.setText("Tab " + mTabNumber + ", Item " + (position + 1)); } @Override public int getItemCount() { return 10; } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(@NonNull View itemView) { super(itemView); mTextView = itemView.findViewById(R.id.text_view); } } } ``` 6. 创建RecyclerView的item布局文件和Fragment布局文件: item_my.xml: ```xml <TextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" /> ``` fragment_my.xml: ```xml <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 这样就完成了实现。每个Tab都显示一个RecyclerView,切换Tab时切换RecyclerView。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值