目錄
- 效果與UI框架
- (1)定義導航欄大致布局
- (2)初步設定導航欄圖示點擊回應事件
- (3)導航欄圖示跟隨viewPager滑動一同變化
- (4)點擊導航欄圖示,切換viewPager
- 更多細節在具體代碼中體現
效果與UI框架
模擬微信首頁的最終實作效果如下圖:

要實作下面導航欄的效果,有很多的實作方案,典型的是navigation,這個控制元件把整個聯動效果都完成了,開發變得非常簡單,在下一章節中再介紹這個簡便高級的辦法
下面硬擼代碼,了解更底層地原理,一行行手寫效果,總的UI框架為:

(1)定義導航欄大致布局
導航欄框

導航欄中的圖示按鈕(其中一個)

點擊按鈕圖示的變化實際上是換了一張圖片

(2)初步設定導航欄圖示點擊回應事件
用圖示所對應的LinearLayout回應點擊事件

布局初始化與設定監聽

在main.xml中參考

(3)導航欄圖示跟隨viewPager滑動一同變化
viewPager既然能夠設定滑動,必然有滑動的監聽介面

要重置狀態,使得按鈕變化正常化(不點擊與點擊對應不同狀態)

(4)點擊導航欄圖示,切換viewPager
完成按鈕的點擊事件

viewPager設定item,實作頁面切換

更多細節在具體代碼中體現
代碼架構

bottom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<!--導航欄布局,方向為水平,顏色為#0E0E0E(灰色)-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="@color/gray"
android:orientation="horizontal">
<!-- 寬度設定為0,權重為1,表示寬度按照LL個數自動分配-->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/id_tab_weixin">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:id="@+id/tab_iv_weixin"
android:background="@drawable/tab_weixin"/>
<TextView
android:layout_width="32dp"
android:layout_height="wrap_content"
android:id="@+id/text_weixin"
android:gravity="center"
android:text="微信"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/id_tab_contact">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:id="@+id/tab_iv_contact"
android:background="@drawable/table_contact"/>
<TextView
android:layout_width="32dp"
android:layout_height="wrap_content"
android:id="@+id/text_contact"
android:gravity="center"
android:text="通訊錄"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/id_tab_find">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:id="@+id/tab_iv_find"
android:background="@drawable/tab_find"/>
<TextView
android:layout_width="32dp"
android:layout_height="wrap_content"
android:id="@+id/text_find"
android:gravity="center"
android:text="發現"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/id_tab_my">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:id="@+id/tab_iv_my"
android:background="@drawable/tab_my"/>
<TextView
android:layout_width="32dp"
android:layout_height="wrap_content"
android:id="@+id/text_my"
android:gravity="center"
android:text="我"/>
</LinearLayout>
</LinearLayout>
tab_find.xml、tab_my.xml、tab_contact.xml與tab_weixin.xml類似
<?xml version="1.0" encoding="utf-8"?>
<!--點擊狀態是一張圖片,非點擊是另外一張-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_baseline_chat_bubble_24" android:state_selected="true"/>
<item android:drawable="@drawable/ic_baseline_chat_bubble_outline_24"/>
</selector>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 高為0權重為1的設定可以讓ViewPager界面自動適配bottom_layout-->
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/viewpage"/>
<!-- 參考bottom_layout.xml-->
<include layout="@layout/bottom_layout"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
ViewPager2 viewPager;
private LinearLayout llWeixin,llContact,llFind,llMy;
//ivCurrent用于保存當前畫面
private ImageView ivWeixin,ivContact,ivFind,ivMy,ivCurrent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//這里的viewPager不再是一個簡單的UI,是一個要控制fragment的UI,要用專門的方法去初始化viewPager
initPager();
initTabView();
}
//這個函式專門處理UI的更新
private void initTabView() {
llWeixin = findViewById(R.id.id_tab_weixin);
llWeixin.setOnClickListener(this);
llContact = findViewById(R.id.id_tab_contact);
llContact.setOnClickListener(this);
llFind = findViewById(R.id.id_tab_find);
llFind.setOnClickListener(this);
llMy = findViewById(R.id.id_tab_my);
llMy.setOnClickListener(this);
ivWeixin = findViewById(R.id.tab_iv_weixin);
ivContact = findViewById(R.id.tab_iv_contact);
ivFind = findViewById(R.id.tab_iv_find);
ivMy = findViewById(R.id.tab_iv_my);
//微信一進來顯示的應該是聊天界面
ivWeixin.setSelected(true);
//設定當前頁面
ivCurrent = ivWeixin;
}
private void initPager() {
viewPager = findViewById(R.id.viewpage);
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(BlankFragment.newInstance("微信聊天"));
fragments.add(BlankFragment.newInstance("通訊錄"));
fragments.add(BlankFragment.newInstance("發現"));
fragments.add(BlankFragment.newInstance("我"));
MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),
getLifecycle(),fragments);//getLifecycle是jetpack里面的一個組件
//系統專門提供了ViewPager適配Fragment的Adapter
viewPager.setAdapter(pagerAdapter);
//viewpager的高級用法:既然能夠設定滑動,必然有滑動的監聽介面
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
//實作影片的滾動動效可以放在這里實作
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
//選擇后改變位置放在這里實作,回應頁面改變
public void onPageSelected(int position) {
super.onPageSelected(position);
//viewpager的滑動對應改變導航欄的UI
changeTab(position);
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
}
//viewpager的滑動對應改變導航欄的UI
private void changeTab(int position) {
//把上一次的圖示點擊事件取消,相當于復位
ivCurrent.setSelected(false);
switch (position) {
case 0:
case R.id.id_tab_weixin:
//導航欄對viewpage的聯動,點擊導航欄切換頁面
viewPager.setCurrentItem(0);
//viewpage對導航欄的聯動,選中為ivWeixin,則對應的圖片被選中
ivWeixin.setSelected(true);
//標記當前圖示
ivCurrent = ivWeixin;
break;
case 1:
case R.id.id_tab_contact:
viewPager.setCurrentItem(1);
//選中為ivWeixin,則對應的圖片被選中
ivContact.setSelected(true);
ivCurrent = ivContact;
break;
case 2:
case R.id.id_tab_find:
viewPager.setCurrentItem(2);
//選中為ivWeixin,則對應的圖片被選中
ivFind.setSelected(true);
ivCurrent = ivFind;
break;
case 3:
case R.id.id_tab_my:
viewPager.setCurrentItem(3);
//選中為ivWeixin,則對應的圖片被選中
ivMy.setSelected(true);
ivCurrent = ivMy;
break;
}
}
@Override
public void onClick(View v) {
changeTab(v.getId());
}
}
最后的關于fragment的fragment_blank.xml、BlankFragment.java、MyFragmentPagerAdapter.java均在上一章節中有,且完全一致,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/279283.html
標籤:其他


