国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Android 實(shí)現(xiàn)錨點(diǎn)定位

dendoink / 516人閱讀

摘要:原文鏈接相信做前端的都做過(guò)頁(yè)面錨點(diǎn)定位的功能,通過(guò)去設(shè)置頁(yè)面內(nèi)錨點(diǎn)定位跳轉(zhuǎn)。本篇文章就使用來(lái)實(shí)現(xiàn)錨點(diǎn)定位的功能。寫(xiě)到這里,的錨點(diǎn)定位成型了,在實(shí)際項(xiàng)目中,我們還可以使用來(lái)完成同樣的效果,后續(xù)的話會(huì)帶來(lái)這樣的文章。

原文鏈接:https://mp.weixin.qq.com/s/EYyTBtM9qCdmB9nlDEF-3w

相信做前端的都做過(guò)頁(yè)面錨點(diǎn)定位的功能,通過(guò) 去設(shè)置頁(yè)面內(nèi)錨點(diǎn)定位跳轉(zhuǎn)。
本篇文章就使用tablayout、scrollview來(lái)實(shí)現(xiàn)android錨點(diǎn)定位的功能。
效果圖:

實(shí)現(xiàn)思路

1、監(jiān)聽(tīng)scrollview滑動(dòng)到的位置,tablayout切換到對(duì)應(yīng)標(biāo)簽
2、tablayout各標(biāo)簽點(diǎn)擊,scrollview可滑動(dòng)到對(duì)應(yīng)區(qū)域

自定義scrollview

因?yàn)槲覀冃枰O(jiān)聽(tīng)到滑動(dòng)過(guò)程中scrollview的滑動(dòng)距離,自定義scrollview通過(guò)接口暴露滑動(dòng)的距離。

public class CustomScrollView extends ScrollView {

    public Callbacks mCallbacks;

    public CustomScrollView(Context context) {
        super(context);
    }

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

    public CustomScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setCallbacks(Callbacks callbacks) {
        this.mCallbacks = callbacks;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mCallbacks != null) {
            mCallbacks.onScrollChanged(l, t, oldl, oldt);
        }
    }
    //定義接口用于回調(diào)
    public interface Callbacks {
        void onScrollChanged(int x, int y, int oldx, int oldy);
    }

}

布局文件里 tablayoutCustomScrollView,內(nèi)容暫時(shí)使用LinearLayout填充。




    

    

        

        

    

數(shù)據(jù)模擬

數(shù)據(jù)模擬,動(dòng)態(tài)添加scrollview內(nèi)的內(nèi)容,這里自定義了AnchorView當(dāng)作每一塊的填充內(nèi)容。

private String[] tabTxt = {"客廳", "臥室", "餐廳", "書(shū)房", "陽(yáng)臺(tái)", "兒童房"};
//內(nèi)容塊view的集合
private List anchorList = new ArrayList<>();
//判讀是否是scrollview主動(dòng)引起的滑動(dòng),true-是,false-否,由tablayout引起的
private boolean isScroll;
//記錄上一次位置,防止在同一內(nèi)容塊里滑動(dòng) 重復(fù)定位到tablayout
private int lastPos;

//模擬數(shù)據(jù),填充scrollview
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);
}

//tablayout設(shè)置標(biāo)簽
for (int i = 0; i < tabTxt.length; i++) {
    tabLayout.addTab(tabLayout.newTab().setText(tabTxt[i]));
}

定義變量標(biāo)志isScroll,用于判斷scrollview的滑動(dòng)由誰(shuí)引起的,避免通過(guò)點(diǎn)擊tabLayout引起的scrollview滑動(dòng)問(wèn)題。
定義變量標(biāo)志lastPos,當(dāng)scrollview 在同一模塊中滑動(dòng)時(shí),則不再去調(diào)用tabLayout.setScrollPosition刷新標(biāo)簽。

自定義的AnchorView

public class AnchorView extends LinearLayout {

    private TextView tvAnchor;
    private TextView tvContent;

    public AnchorView(Context context) {
        this(context, null);
    }

    public AnchorView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AnchorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.view_anchor, this, true);
        tvAnchor = view.findViewById(R.id.tv_anchor);
        tvContent = view.findViewById(R.id.tv_content);
        Random random = new Random();
        int r = random.nextInt(256);
        int g = random.nextInt(256);
        int b = random.nextInt(256);
        tvContent.setBackgroundColor(Color.rgb(r, g, b));
    }

    public void setAnchorTxt(String txt) {
        tvAnchor.setText(txt);
    }

    public void setContentTxt(String txt) {
        tvContent.setText(txt);
    }
}
實(shí)現(xiàn)

scrollview的滑動(dòng)監(jiān)聽(tīng):

scrollView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //當(dāng)由scrollview觸發(fā)時(shí),isScroll 置true
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            isScroll = true;
        }
        return false;
    }
});

scrollView.setCallbacks(new CustomScrollView.Callbacks() {
    @Override
    public void onScrollChanged(int x, int y, int oldx, int oldy) {
        if (isScroll) {
            for (int i = tabTxt.length - 1; i >= 0; i--) {
                //根據(jù)滑動(dòng)距離,對(duì)比各模塊距離父布局頂部的高度判斷
                if (y > anchorList.get(i).getTop() - 10) {
                    setScrollPos(i);
                    break;
                }
            }
        }
    }
});

//tablayout對(duì)應(yīng)標(biāo)簽的切換
private void setScrollPos(int newPos) {
    if (lastPos != newPos) {
        //該方法不會(huì)觸發(fā)tablayout 的onTabSelected 監(jiān)聽(tīng)
        tabLayout.setScrollPosition(newPos, 0, true);
    }
    lastPos = newPos;
}

tabLayout的點(diǎn)擊切換:

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        //點(diǎn)擊標(biāo)簽,使scrollview滑動(dòng),isScroll置false
        isScroll = false;
        int pos = tab.getPosition();
        int top = anchorList.get(pos).getTop();
        scrollView.smoothScrollTo(0, top);
    }

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

    }

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

    }
});

至此效果出來(lái)了,但是
問(wèn)題來(lái)了 可以看到當(dāng)點(diǎn)擊最后一項(xiàng)時(shí),scrollView滑動(dòng)到底部時(shí)并沒(méi)有呈現(xiàn)出我們想要的效果,希望滑到最后一個(gè)時(shí),全屏只有最后一塊內(nèi)容顯示。
所以這里需要處理下最后一個(gè)view的高度,當(dāng)不滿(mǎn)全屏?xí)r,重新設(shè)置他的高度,通過(guò)計(jì)算讓其撐滿(mǎn)屏幕。

//監(jiān)聽(tīng)判斷最后一個(gè)模塊的高度,不滿(mǎn)一屏?xí)r讓最后一個(gè)模塊撐滿(mǎn)屏幕
private ViewTreeObserver.OnGlobalLayoutListener listener;

listener = new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int screenH = getScreenHeight();
        int statusBarH = getStatusBarHeight(MainActivity.this);
        int tabH = tabLayout.getHeight();
        //計(jì)算內(nèi)容塊所在的高度,全屏高度-狀態(tài)欄高度-tablayout的高度-內(nèi)容container的padding 16dp
        int lastH = screenH - statusBarH - tabH - 16 * 3;
        AnchorView lastView = anchorList.get(anchorList.size() - 1);
        //當(dāng)最后一個(gè)view 高度小于內(nèi)容塊高度時(shí),設(shè)置其高度撐滿(mǎn)
        if (lastView.getHeight() < lastH) {
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.height = lastH;
            lastView.setLayoutParams(params);
        }
        container.getViewTreeObserver().removeOnGlobalLayoutListener(listener);

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

這樣就達(dá)到了預(yù)期的效果了。

寫(xiě)到這里,tablayout + scrollview的錨點(diǎn)定位成型了,在實(shí)際項(xiàng)目中,我們還可以使用tablayout + recyclerview 來(lái)完成同樣的效果,后續(xù)的話會(huì)帶來(lái)這樣的文章。

這段時(shí)間自己在做一個(gè)小程序,包括數(shù)據(jù)爬取 + 后臺(tái) + 小程序的,可能要過(guò)段時(shí)間才能出來(lái),主要是數(shù)據(jù)爬蟲(chóng)那邊比較麻煩的...期待下!

詳細(xì)代碼見(jiàn)
github地址:https://github.com/taixiang/tabScroll

歡迎關(guān)注我的博客:https://blog.manjiexiang.cn/
更多精彩歡迎關(guān)注微信號(hào):春風(fēng)十里不如認(rèn)識(shí)你

有個(gè)「佛系碼農(nóng)圈」,歡迎大家加入暢聊,開(kāi)心就好!

過(guò)期了,可加我微信 tx467220125 拉你入群。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/76440.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

dendoink

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<