最近在心血來潮想寫在app 不過我關于android可以說是0基礎 在寫底部導航欄的時候去問了大佬才知道TabLayout和ViewPager 花了兩天才看懂...
這里只是簡單介紹因為我不準備專門做安卓軟件所以在學的途中很多地方?jīng)]有認真記
介紹
本篇文章使用的代碼是Java
這里官方是有將兩個進行聯(lián)動的方法的 當然如果不用也可以做 只不過應該沒人會這樣寫...
TabLayout
關于TabLayout給我的第一感覺是真的強大 而大部分情況TabLayout都是用于做導航欄的(也是暫時沒想出來還可以做什么)
ViewPager
而ViewPager主要是用于做頁面滾動 滑動頁面 等
這里頁面滾動和滑動頁面是兩個東西 頁面滾動就是類似于在瀏覽某寶或新聞網(wǎng)站時遇到的滾動效果 頁面滑動是用戶用手指滑動頁面(左滑或右滑) 而這里的滾動是自動的由程序設置定時器的方式滾動 當然也可以手動滑動 頁面滑動只是用戶用手指去滑動
代碼
layout_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/father_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".Main">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.google.android.material.tabs.TabLayout
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:tabGravity="fill"
app:tabIconTint="@color/tab_layout"
app:tabIndicatorFullWidth="true"
app:tabIndicatorGravity="top"
app:tabIndicatorHeight="2dp"
app:tabMode="fixed"
app:tabRippleColor="#ADD8E6"
app:tabUnboundedRipple="true"/>
</RelativeLayout>
可以看到在我的layout_main文件里我定義TabLayout與ViewPager2
需要注意的是這里的ViewPager2和ViewPager是有區(qū)別的 一會介紹
由于我沒記住TabLayout的屬性所以就放文章給大家了....
TabLayout屬性介紹:TabLayout屬性介紹
Main.java
package com.javabot.demo;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;
import com.daimajia.androidanimations.library.Techniques;
import com.daimajia.androidanimations.library.YoYo;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.javabot.demo.fragment.FragmentCommunity;
import com.javabot.demo.fragment.FragmentContact;
import com.javabot.demo.fragment.FragmentDocumentation;
import com.javabot.demo.fragment.FragmentHomePage;
import com.javabot.demo.utils.MyFragmentPagerAdapter;
import com.javabot.demo.utils.svg;
import java.util.ArrayList;
import java.util.List;
/**
* 主程序
*
* @author 白
*/
public class Main extends AppCompatActivity {
private final Context context = this;
/**
* 工具 svg對象
*/
private final svg svg = new svg(context);
private int[] tabIconView = {
R.drawable.home,
R.drawable.megaphone,
R.drawable.paper_plane,
R.drawable.user
};
/**
* 自定義view
*
* @param icon svg
* @return View
*/
private View setCustomView(int icon) {
View v = View.inflate(context, R.layout.custom_view, null);
ImageView i = v.findViewById(R.id.CustomViewImage);
i.setImageTintList(ContextCompat.getColorStateList(context, R.color.tab_layout));
i.setImageDrawable(svg.svgImage(icon));
return v;
}
/**
* TabLayout關聯(lián)ViewPager2
*/
private void addMyFragmentPagerAdapter() {
List<Fragment> fragmentList = new ArrayList<>();
FragmentHomePage homePage = new FragmentHomePage();
FragmentCommunity community = new FragmentCommunity();
FragmentContact contact = new FragmentContact();
FragmentDocumentation documentation = new FragmentDocumentation(context);
fragmentList.add(homePage);
fragmentList.add(community);
fragmentList.add(contact);
fragmentList.add(documentation);
MyFragmentPagerAdapter fragmentAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),getLifecycle(), fragmentList);
TabLayout tabLayout = findViewById(R.id.navigation);
ViewPager2 viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(fragmentAdapter);
new TabLayoutMediator(tabLayout, viewPager,
(tab, position) -> {
tab.setIcon(tabIconView[position]);
}
).attach();
// 監(jiān)聽頁面切換事件
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
// 更新TabLayout的選中狀態(tài)
tabLayout.selectTab(tabLayout.getTabAt(position));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
YoYo.with(Techniques.RubberBand)
.duration(700)
.playOn(tab.view);
}
});
}
});
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
addMyFragmentPagerAdapter();
}
}
主要關聯(lián)的代碼在addMyFragmentPagerAdapter方法中
這里我們將代碼一點點拆解介紹
addMyFragmentPagerAdapte方法
這里的代碼都是按照addMyFragmentPagerAdapte方法中的代碼一行一行的講解 所以看到不知道的變量時請往上瞅瞅
List<Fragment> fragmentList = new ArrayList<>();
這里是創(chuàng)建視圖存儲器的 這個就看各位喜好了 也可以用Map或數(shù)組
ViewPager2的視圖對象需要是Fragment而不是View 因為適配器需要
關于ViewPager2的詳細介紹請移步
ViewPagers2
FragmentHomePage homePage = new FragmentHomePage();
FragmentCommunity community = new FragmentCommunity();
FragmentContact contact = new FragmentContact();
FragmentDocumentation documentation = new FragmentDocumentation(context);
fragmentList.add(homePage);
fragmentList.add(community);
fragmentList.add(contact);
fragmentList.add(documentation);
創(chuàng)建視圖對象并添加到集合中 這一步?jīng)]什么好說的 視圖對象會在下面放出來
MyFragmentPagerAdapter fragmentAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),getLifecycle(), fragmentList);
創(chuàng)建適配器對象 適配器會在下面放出來
TabLayout tabLayout = findViewById(R.id.navigation);
ViewPager2 viewPager = findViewById(R.id.view_pager);
獲取xml文件中的視圖id?這里也沒什么好說的
viewPager.setAdapter(fragmentAdapter);
設置ViewPager2適配器fragmentAdapter由適配器對象獲得
new TabLayoutMediator(tabLayout, viewPager,
(tab, position) -> {
tab.setIcon(tabIconView[position]);
}).attach();
將TabLayout和ViewPager2關聯(lián)
而這里的
tab.setIcon(tabIconView[position]);
就是在里面的代碼是用于設置TabLayout顯示的內(nèi)容的 這邊這個可以自己按需求更改
// 監(jiān)聽頁面切換事件
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
// 更新TabLayout的選中狀態(tài)
tabLayout.selectTab(tabLayout.getTabAt(position));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
YoYo.with(Techniques.RubberBand)
.duration(700)
.playOn(tab.view);
}
});
}
});
這里就和備注的一樣 和平常的監(jiān)聽事件相同這里可寫可不寫
需要拿出來說的是
YoYo.with(Techniques.RubberBand)
.duration(700)
.playOn(tab.view);
這是一個名叫悠悠球的動畫庫
這里是官網(wǎng)介紹:YoYo
依賴如下
//悠悠球動畫庫
implementation 'com.daimajia.androidanimations:library:2.4@aar'
適配器?FragmentStateAdapter對象
package com.javabot.demo.utils;
import static androidx.viewpager.widget.PagerAdapter.POSITION_NONE;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.List;
/**
* 適配器對象
* @author 白
*/
public class MyFragmentPagerAdapter extends FragmentStateAdapter {
private final List<Fragment> fragmentList;
public MyFragmentPagerAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, List<Fragment> fragmentList) {
super(fragmentManager, lifecycle);
this.fragmentList = fragmentList;
}
public MyFragmentPagerAdapter(FragmentActivity fm, List<Fragment> fragmentList) {
super(fm);
this.fragmentList=fragmentList;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragmentList.get(position);
}
@Override
public int getItemCount() {
return fragmentList.size();
}
@Override
public long getItemId(int position) {
return fragmentList.get(position).hashCode();
}
}
這里的適配器你需要重寫的方法有getItemCount和createFragment
這里也只介紹這兩個方法
getItemCount方法
此方法返回的是視圖的個數(shù) 例如我想要顯示4個視圖那就返回4 如果我給適配器傳的視圖有6個或者更多但是這個方法只返回4那也只會顯示4個視圖
createFragment方法
這個方法返回的是視圖而此方法中的參數(shù)position 代表當前是哪個視圖 返回對應視圖的下標(從0開始)
例如我在這個方法中寫if判斷 position==0 再返回某個視圖對象 那他的意思其實就是當用戶點擊到下標為0的那個選項時(或滑動)當前視圖顯示的內(nèi)容就是我這里所返回的視圖內(nèi)容
視圖文件?Fragment對象
package com.javabot.demo.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.javabot.demo.R;
/**
* 主頁視圖
*/
public class FragmentHomePage extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_page,container,false);
}
}
剩下的和這個一樣就不發(fā)出來了
和視圖文件所對應的xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="主頁"/>
</RelativeLayout>
這里都差不多就不放出來了
效果圖
?文章來源地址http://www.zghlxwxcb.cn/news/detail-822719.html文章來源:http://www.zghlxwxcb.cn/news/detail-822719.html
?
到了這里,關于android 關于TabLayout聯(lián)動ViewPager2 實現(xiàn)底部導航欄的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!