国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android 實現錨點定位思路詳解

2019-10-21 21:45:52
字體:
來源:轉載
供稿:網友

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

本篇文章就使用tablayout、scrollview來實現android錨點定位的功能。

效果圖:

Android,錨點,定位

實現思路

1、監聽scrollview滑動到的位置,tablayout切換到對應標簽

2、tablayout各標簽點擊,scrollview可滑動到對應區域

自定義scrollview

因為我們需要監聽到滑動過程中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);  } } //定義接口用于回調 public interface Callbacks {  void onScrollChanged(int x, int y, int oldx, int oldy); }}

布局文件里 tablayout 和 CustomScrollView,內容暫時使用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>

數據模擬

數據模擬,動態添加scrollview內的內容,這里自定義了AnchorView當作每一塊的填充內容。

private String[] tabTxt = {"客廳", "臥室", "餐廳", "書房", "陽臺", "兒童房"};//內容塊view的集合private List<AnchorView> anchorList = new ArrayList<>();//判讀是否是scrollview主動引起的滑動,true-是,false-否,由tablayout引起的private boolean isScroll;//記錄上一次位置,防止在同一內容塊里滑動 重復定位到tablayoutprivate int lastPos;//模擬數據,填充scrollviewfor (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設置標簽for (int i = 0; i < tabTxt.length; i++) { tabLayout.addTab(tabLayout.newTab().setText(tabTxt[i]));}

定義變量標志isScroll,用于判斷scrollview的滑動由誰引起的,避免通過點擊tabLayout引起的scrollview滑動問題。

定義變量標志lastPos,當scrollview 在同一模塊中滑動時,則不再去調用tabLayout.setScrollPosition刷新標簽。

自定義的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); }}

實現

scrollview的滑動監聽:

scrollView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) {  //當由scrollview觸發時,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--) {    //根據滑動距離,對比各模塊距離父布局頂部的高度判斷    if (y > anchorList.get(i).getTop() - 10) {     setScrollPos(i);     break;    }   }  } }});//tablayout對應標簽的切換private void setScrollPos(int newPos) { if (lastPos != newPos) {  //該方法不會觸發tablayout 的onTabSelected 監聽  tabLayout.setScrollPosition(newPos, 0, true); } lastPos = newPos;}tabLayout的點擊切換:tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) {  //點擊標簽,使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) { }});

至此效果出來了,但是

Android,錨點,定位

問題來了 可以看到當點擊最后一項時,scrollView滑動到底部時并沒有呈現出我們想要的效果,希望滑到最后一個時,全屏只有最后一塊內容顯示。

所以這里需要處理下最后一個view的高度,當不滿全屏時,重新設置他的高度,通過計算讓其撐滿屏幕。

//監聽判斷最后一個模塊的高度,不滿一屏時讓最后一個模塊撐滿屏幕private ViewTreeObserver.OnGlobalLayoutListener listener;listener = new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() {  int screenH = getScreenHeight();  int statusBarH = getStatusBarHeight(MainActivity.this);  int tabH = tabLayout.getHeight();  //計算內容塊所在的高度,全屏高度-狀態欄高度-tablayout的高度-內容container的padding 16dp  int lastH = screenH - statusBarH - tabH - 16 * 3;  AnchorView lastView = anchorList.get(anchorList.size() - 1);  //當最后一個view 高度小于內容塊高度時,設置其高度撐滿  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);

這樣就達到了預期的效果了。

Android,錨點,定位

寫到這里,tablayout + scrollview的錨點定位成型了,在實際項目中,我們還可以使用tablayout + recyclerview 來完成同樣的效果,后續的話會帶來這樣的文章。

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

詳細代碼見

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

總結

以上所述是小編給大家介紹的Android 實現錨點定位思路詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VEVB武林網網站的支持!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 澎湖县| 晋中市| 揭东县| 铜山县| 云安县| 文昌市| 竹溪县| 澄江县| 古浪县| 台州市| 太仆寺旗| 武威市| 布尔津县| 平原县| 岳池县| 得荣县| 南宁市| 南昌县| 渭源县| 万源市| 如东县| 沽源县| 乐都县| 射洪县| 开平市| 静安区| 洪泽县| 沙坪坝区| 德安县| 思茅市| 玉环县| 桐乡市| 宝山区| 镇赉县| 新乡市| 思南县| 台北县| 海口市| 萝北县| 丰宁| 荥阳市|