Androidスライド位置決め+吸着サスペンション効果実現

11660 ワード

前の2つの記事では、tablayout+scrollviewとtablayout+recyclerviewで実現したスライド位置決めの機能をそれぞれ紹介しています.記事リンク:Androidでアンカー位置決めAndroid tabLayout+recyclerViewで実現してアンカー位置決めを実現します.よく見ると、このスライド位置決めの機能は、全体的にスライドすることもできますし、上部tablayout吸着サスペンションの効果も加わります.
効果:
レイアウト
ここでは2つのtablayoutを採用しています.元の位置に位置し、scrollviewの内部にあり、scrollviewに従ってスクロールするための占有.もう1つは、スライド中にスライドを続け、上部にスライドすると画面上部に吸着し、ユーザーが実際に操作しているのもこのtablayoutです.
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    "@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        "match_parent"
            android:layout_height="match_parent">

            "match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                "match_parent"
                    android:layout_height="200dp"
                    android:background="#ccc"
                    android:gravity="center">

                    "wrap_content"
                        android:layout_height="wrap_content"
                        android:text="         "
                        android:textSize="16sp" />

                

                
                "@+id/tablayout_holder"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:background="#ffffff"
                    app:tabIndicatorColor="@color/colorPrimary"
                    app:tabMode="scrollable"
                    app:tabSelectedTextColor="@color/colorPrimary" />

                "@+id/container"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:padding="16dp" />

            


            
            "@+id/tablayout_real"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#ffffff"
                android:visibility="invisible"
                app:tabIndicatorColor="@color/colorPrimary"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="@color/colorPrimary" />
        


    



インプリメンテーション
スライド位置決めの機能は,従来の文書を参照することができ,ここでは主に吸着サスペンションの効果を行う.
データの初期化:
/**
 *   tablayout,             tablayout   
 */
private TabLayout holderTabLayout;
/**
 *      tablayout,
 */
private TabLayout realTabLayout;
private CustomScrollView scrollView;
private LinearLayout container;
private String[] tabTxt = {"  ", "  ", "  ", "  ", "  ", "   "};

private List anchorList = new ArrayList<>();

//     scrollview       ,true- ,false- , tablayout   
private boolean isScroll;
//       ,                 tablayout
private int lastPos = 0;
//             ,                
private ViewTreeObserver.OnGlobalLayoutListener listener;

for (int i = 0; i < tabTxt.length; i++) {
    AnchorView anchorView = new AnchorView(this);
    anchorView.setAnchorTxt(tabTxt[i]);
    anchorView.setContentTxt(tabTxt[i]);
    anchorList.add(anchorView);
    container.addView(anchorView);
}
for (int i = 0; i < tabTxt.length; i++) {
    holderTabLayout.addTab(holderTabLayout.newTab().setText(tabTxt[i]));
    realTabLayout.addTab(realTabLayout.newTab().setText(tabTxt[i]));
}


最初は実際のtablayoutを占有するtablayoutに移動させ、占有するtablayoutを上書きする.
listener = new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //       view      
        int screenH = getScreenHeight();
        int statusBarH = getStatusBarHeight(AliHomeMoreActivity.this);
        int tabH = holderTabLayout.getHeight();
        int lastH = screenH - statusBarH - tabH - 16 * 3;
        AnchorView anchorView = anchorList.get(anchorList.size() - 1);
        if (anchorView.getHeight() < lastH) {
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.height = lastH;
            anchorView.setLayoutParams(params);
        }

        //       tablayout        tablayout ,     tablayout
        realTabLayout.setTranslationY(holderTabLayout.getTop());
        realTabLayout.setVisibility(View.VISIBLE);
        container.getViewTreeObserver().removeOnGlobalLayoutListener(listener);

    }
};
container.getViewTreeObserver().addOnGlobalLayoutListener(listener);

private int getScreenHeight() {
    return getResources().getDisplayMetrics().heightPixels;
}

public int getStatusBarHeight(Context context) {
    int result = 0;
    int resourceId = context.getResources()
            .getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

scrollviewスライド
主にスライド過程でスライドの距離を絶えず監視し、実際のtablayoutを移動し、画面内にいる間、占有されたtablayoutにずっと覆わせ、scrollviewと一緒にスライドしているように見えます.画面をスライドさせると、実際のtablayoutは画面に対して静止し、画面の上部に吸着しているように見えます.
scrollView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            isScroll = true;
        }
        return false;
    }
});

//  scrollview  
scrollView.setCallbacks(new CustomScrollView.Callbacks() {
    @Override
    public void onScrollChanged(int x, int y, int oldx, int oldy) {
        //       y(     )   holderTabLayout          (        )  ,
        // y < holderTabLayout.getTop() ,holderTabLayout      ,realTabLayout    holderTabLayout.getTop()  ,  holderTabLayout
        // y > holderTabLayout.getTop() ,holderTabLayout   ,realTabLayout    y,        ,       
        int translation = Math.max(y, holderTabLayout.getTop());
        realTabLayout.setTranslationY(translation);

        if (isScroll) {
            for (int i = tabTxt.length - 1; i >= 0; i--) {
                //  y           (        ,  demo   200dp)
                if (y - 200 * 3 > anchorList.get(i).getTop() - 10) {
                    setScrollPos(i);
                    break;
                }
            }
        }

    }
});

private void setScrollPos(int newPos) {
    if (lastPos != newPos) {
        realTabLayout.setScrollPosition(newPos, 0, true);
    }
    lastPos = newPos;
}

tablayoutクリック切り替え
実際にはrealtablayoutが操作されているため、ここではtablayoutを常に監視する必要があります.
//   tablayout     
realTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        isScroll = false;
        int pos = tab.getPosition();
        int top = anchorList.get(pos).getTop();
        //                  (       )
        scrollView.smoothScrollTo(0, top + 200 * 3);
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});


これでスライド位置決め+トップ吸着サスペンションの効果は終了した.终わったら、この効果を见て、実は支付宝-トップページのもっと多くのページのスライド効果と同じです.コードは前の文章と同じgitアドレスにあります.
詳細コードはgithubアドレス:github.com/taixiang/ta…
私のブログへようこそ:blog.manjiexiang.cn/もっとすばらしいマイクロ信号に注目することを歓迎します:春風十里はあなたを知っているほうがいいです
「仏系私たちの輪」があります.皆さん、楽しく話してください.
期限が切れたので、私の微信tx 467220125を加えてあなたをグループに入れることができます.