最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2018年07月23日 08:31:06   作者:程序猿tx  
本篇文章就使用tablayout、scrollview來實(shí)現(xiàn)android錨點(diǎn)定位的功能。通過<a href="#head" rel="external nofollow" > 去設(shè)置頁面內(nèi)錨點(diǎn)定位跳轉(zhuǎn)。具體實(shí)現(xiàn)思路大家跟隨腳本之家小編一起通過本文看下吧

相信做前端的都做過頁面錨點(diǎn)定位的功能,通過<a href="#head" rel="external nofollow" > 去設(shè)置頁面內(nèi)錨點(diǎn)定位跳轉(zhuǎn)。

本篇文章就使用tablayout、scrollview來實(shí)現(xiàn)android錨點(diǎn)定位的功能。

效果圖:

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

1、監(jiān)聽scrollview滑動到的位置,tablayout切換到對應(yīng)標(biāo)簽

2、tablayout各標(biāo)簽點(diǎn)擊,scrollview可滑動到對應(yīng)區(qū)域

自定義scrollview

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

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);
 }
}

布局文件里 tablayout 和 CustomScrollView,內(nèi)容暫時使用LinearLayout填充。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="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">
 <android.support.design.widget.TabLayout
  android:id="@+id/tablayout"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  app:tabIndicatorColor="@color/colorPrimary"
  app:tabMode="scrollable"
  app:tabSelectedTextColor="@color/colorPrimary" />
 <com.tabscroll.CustomScrollView
  android:id="@+id/scrollView"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:fillViewport="true"
  android:fitsSystemWindows="true">
  <LinearLayout
   android:id="@+id/container"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical"
   android:padding="16dp">
  </LinearLayout>
 </com.tabscroll.CustomScrollView>
</LinearLayout>

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

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

private String[] tabTxt = {"客廳", "臥室", "餐廳", "書房", "陽臺", "兒童房"};
//內(nèi)容塊view的集合
private List<AnchorView> anchorList = new ArrayList<>();
//判讀是否是scrollview主動引起的滑動,true-是,false-否,由tablayout引起的
private boolean isScroll;
//記錄上一次位置,防止在同一內(nèi)容塊里滑動 重復(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的滑動由誰引起的,避免通過點(diǎn)擊tabLayout引起的scrollview滑動問題。

定義變量標(biāo)志lastPos,當(dāng)scrollview 在同一模塊中滑動時,則不再去調(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的滑動監(jiān)聽:

scrollView.setOnTouchListener(new View.OnTouchListener() {
 @Override
 public boolean onTouch(View v, MotionEvent event) {
  //當(dāng)由scrollview觸發(fā)時,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ù)滑動距離,對比各模塊距離父布局頂部的高度判斷
    if (y > anchorList.get(i).getTop() - 10) {
     setScrollPos(i);
     break;
    }
   }
  }
 }
});
//tablayout對應(yīng)標(biāo)簽的切換
private void setScrollPos(int newPos) {
 if (lastPos != newPos) {
  //該方法不會觸發(fā)tablayout 的onTabSelected 監(jiān)聽
  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滑動,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) {
 }
});

至此效果出來了,但是

問題來了 可以看到當(dāng)點(diǎn)擊最后一項(xiàng)時,scrollView滑動到底部時并沒有呈現(xiàn)出我們想要的效果,希望滑到最后一個時,全屏只有最后一塊內(nèi)容顯示。

所以這里需要處理下最后一個view的高度,當(dāng)不滿全屏?xí)r,重新設(shè)置他的高度,通過計(jì)算讓其撐滿屏幕。

//監(jiān)聽判斷最后一個模塊的高度,不滿一屏?xí)r讓最后一個模塊撐滿屏幕
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)最后一個view 高度小于內(nèi)容塊高度時,設(shè)置其高度撐滿
  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ù)期的效果了。

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

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

詳細(xì)代碼見

github地址:https://github.com/taixiang/tabScroll

總結(jié)

以上所述是小編給大家介紹的Android 實(shí)現(xiàn)錨點(diǎn)定位思路詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • onMeasure被執(zhí)行兩次原理解析

    onMeasure被執(zhí)行兩次原理解析

    這篇文章主要為大家介紹了onMeasure被執(zhí)行兩次原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • android電源信息查看(電量、溫度、電壓)實(shí)例代碼

    android電源信息查看(電量、溫度、電壓)實(shí)例代碼

    這篇文章主要介紹了android電源信息查看方法,以實(shí)例形式較為詳細(xì)的分析了Android實(shí)現(xiàn)電源電量、電壓、溫度等信息查看的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • Android 畫中畫模式的實(shí)現(xiàn)示例

    Android 畫中畫模式的實(shí)現(xiàn)示例

    這篇文章主要介紹了Android 畫中畫模式的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • android實(shí)現(xiàn)上下滾動的TextView

    android實(shí)現(xiàn)上下滾動的TextView

    android實(shí)現(xiàn)上下滾動的TextView,需要的朋友可以參考一下
    2013-05-05
  • Android開發(fā)實(shí)現(xiàn)讀取excel數(shù)據(jù)并保存為xml的方法

    Android開發(fā)實(shí)現(xiàn)讀取excel數(shù)據(jù)并保存為xml的方法

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)讀取excel數(shù)據(jù)并保存為xml的方法,涉及Android針對Excel數(shù)據(jù)讀取及xml格式文件的構(gòu)造與保存相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • Android使用Item Swipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能

    Android使用Item Swipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能

    大家都用過QQ,肯定有人好奇QQ滑動刪除Item的效果是怎樣實(shí)現(xiàn)的,其實(shí)我們使用Swipemenulistview就可以簡單的實(shí)現(xiàn)。這篇文章主要介紹了Android使用ItemSwipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能,需要的朋友可以參考下
    2017-02-02
  • Android中的常用尺寸單位(dp、sp)快速入門教程

    Android中的常用尺寸單位(dp、sp)快速入門教程

    本文詳細(xì)介紹了Android開發(fā)中常用尺寸單位的含義,重點(diǎn)講解了sp與dp這兩個尺寸單位的本質(zhì)以及它們與px的換算公式,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-05-05
  • Android自定義照相機(jī)Camera出現(xiàn)黑屏的解決方法

    Android自定義照相機(jī)Camera出現(xiàn)黑屏的解決方法

    這篇文章主要介紹了Android自定義照相機(jī)Camera出現(xiàn)黑屏的解決方法,分析了黑屏出現(xiàn)的原因及參考解決方法,需要的朋友可以參考下
    2016-08-08
  • android6.0權(quán)限動態(tài)申請框架permissiondispatcher的方法

    android6.0權(quán)限動態(tài)申請框架permissiondispatcher的方法

    下面小編就為大家分享一篇android6.0權(quán)限動態(tài)申請框架permissiondispatcher的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Android中post和get的提交方式【三種】

    Android中post和get的提交方式【三種】

    本文主要對Android中三種POST和GET的提交方式進(jìn)行詳細(xì)介紹。通過任何一種方式可以實(shí)現(xiàn)的功能是,從安卓手機(jī)端提交數(shù)據(jù)到服務(wù)器端,服務(wù)器端進(jìn)行判斷,并返回相應(yīng)的結(jié)果。三種方式各有利弊,實(shí)現(xiàn)效果相同,在實(shí)際的使用過程中可以根據(jù)本身的需要進(jìn)行選擇。
    2016-12-12

最新評論

通城县| 崇明县| 商水县| 潍坊市| 偏关县| 定兴县| 台中县| 满城县| 麻阳| 沧源| 乡宁县| 丽江市| 平和县| 比如县| 凭祥市| 泰和县| 汉阴县| 五大连池市| 满洲里市| 平舆县| 沁水县| 乐平市| 关岭| 昌都县| 甘德县| 嘉禾县| 南部县| 若尔盖县| 牡丹江市| 壶关县| 广灵县| 朔州市| 临汾市| 太仆寺旗| 泗洪县| 崇阳县| 西平县| 高密市| 固镇县| 怀来县| 岐山县|