昨夜西风凋碧树,独上高楼,望尽天涯路。
今天难得有时间,准备写一写我们在APP中经常用到的页面形式,废话不多说,直接一张图看看页面效果你就知道为啥是常用的页面形式。先看看逻辑和最后的效果是怎么样的:
底部导航栏的实现:底部用Linearlayout放控件以供点击,点击相应的功能就动态加载相应的Fragment。
滑动的实现:首先要有一个Fragment的List,然后编写viewpager的Adapter并绑定,最后不要忘了绑定TabLayout和Viewpager。
图1:HomeFragment界面的第一个Tab(华为)处
图2:HomeFragment界面的第二个Tab(OPPO)处
图3:MessageFragment界面
如上图1所示,底部是一个导航栏,分别对应四个功能模块,每个功能模块都是用Fragment实现的,我们先来看看这个是怎么实现的。
//首先是整个主页面的布局代码,主页是一个FrameLayout和底部的导航栏,代码不难理解。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="@+id/home_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/lin1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_marginTop="10dp"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/homelab" />
<TextView
android:id="@+id/t1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="主页" />
</LinearLayout>
<LinearLayout
android:id="@+id/lin2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_marginTop="10dp"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/messagelab" />
<TextView
android:id="@+id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="消息" />
</LinearLayout>
<LinearLayout
android:id="@+id/lin3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_marginTop="10dp"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/mine" />
<TextView
android:id="@+id/t3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="我的" />
</LinearLayout>
<LinearLayout
android:id="@+id/lin4"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_marginTop="10dp"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/settings" />
<TextView
android:id="@+id/t4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="设置" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
然后我们来看看HomeActivity的代码。每个Fragment的代码都是最基础的Fragment,需要注意别引错包就行。Fragment的代码只贴一个
//核心
public class HomeActivity extends FragmentActivity {
private static final String TAG = "HomeActivity";
private LinearLayout homeLin,messageLin,mineLin,settingLin;
private TextView textView1,textView2,textView3,textView4;
private Fragment homeFragment,messageFragment,mineFragment,settingFragment;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//控件等的初始化
homeLin=findViewById(R.id.lin1);
messageLin=findViewById(R.id.lin2);
mineLin=findViewById(R.id.lin3);
settingLin=findViewById(R.id.lin4);
textView1=findViewById(R.id.t1);
textView2=findViewById(R.id.t2);
textView3=findViewById(R.id.t3);
textView4=findViewById(R.id.t4);
homeLin.setOnClickListener(listener);
messageLin.setOnClickListener(listener);
mineLin.setOnClickListener(listener);
settingLin.setOnClickListener(listener);
//默认选中第一个Fragment,也就是主页的Fragment
setTabSelect(0);
}
View.OnClickListener listener=new View.OnClickListener() {
//点击切换页面
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.lin1:
setTabSelect(0);
break;
case R.id.lin2:
setTabSelect(1);
break;
case R.id.lin3:
setTabSelect(2);
break;
case R.id.lin4:
setTabSelect(3);
break;
}
}
};
//实现页面切换的核心代码,主要过程是动态加载Fragment
private void setTabSelect(int index){
initTextColor();
if (fragmentManager==null){
fragmentManager=getSupportFragmentManager();
}
FragmentTransaction ft=fragmentManager.beginTransaction();
hideAllFragment(ft);
switch (index){
case 0:
if (homeFragment==null){
homeFragment=new HomeFragment();
ft.add(R.id.home_content,homeFragment);
Log.e(TAG, "setTabSelect: eeeeee" );
}else {
ft.show(homeFragment);
}
textView1.setTextColor(Color.parseColor("#1C86EE"));
break;
case 1:
if (messageFragment==null){
messageFragment=new MessageFragment();
ft.add(R.id.home_content,messageFragment);
}
ft.show(messageFragment);
textView2.setTextColor(Color.parseColor("#1C86EE"));
break;
case 2:
if (mineFragment==null){
mineFragment=new MineFragment();
ft.add(R.id.home_content,mineFragment);
}
ft.show(mineFragment);
textView3.setTextColor(Color.parseColor("#1C86EE"));
break;
case 3:
if (settingFragment==null){
settingFragment=new SettingFragment();
ft.add(R.id.home_content,settingFragment);
}
ft.show(settingFragment);
textView4.setTextColor(Color.parseColor("#1C86EE"));
break;
}
ft.commit();
}
private void initTextColor() {
//一般情况下点击之后图标和文字都会改变颜色,我这里只做了文字颜色的改变,图标同理
textView1.setTextColor(Color.parseColor("#FF0000"));
textView2.setTextColor(Color.parseColor("#FF0000"));
textView3.setTextColor(Color.parseColor("#FF0000"));
textView4.setTextColor(Color.parseColor("#FF0000"));
}
//避免页面覆盖
private void hideAllFragment(FragmentTransaction fragmentTransaction) {
if(homeFragment!=null){
fragmentTransaction.hide(homeFragment);
}
if(messageFragment!=null){
fragmentTransaction.hide(messageFragment);
}if(mineFragment!=null){
fragmentTransaction.hide(mineFragment);
}if(settingFragment!=null){
fragmentTransaction.hide(settingFragment);
}
}
}
//MessageFragment代码示例:
public class MessageFragment extends Fragment {
private View view;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_message,container,false);
return view;
}
}
//MessageFragment的布局:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="MessageFragment"
android:textSize="30sp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
好了,第一个主要的页面实现就介绍完了,下面是在HomeFragment中用Tablayout+Viewpager+Fragment实现滑动切换页面的功能(点击也可切换)
首先是依赖引入来使用Tablayout
implementation ‘com.android.support:design:28.1.1’
下面来看看Homefragment的布局
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="40dp"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
然后是HomeFragment的代码:
public class HomeFragment extends Fragment {
private ViewPager viewPager;
private ArrayList<Fragment> list=new ArrayList<>();
private ArrayList<String> title=new ArrayList<>();
private OneFragment oneFragment;
private TwoFragment twoFragment;
private ThreeFragment threeFragment;
private FourFragment fourFragment;
private FiveFragment fiveFragment;
private TabLayout tableLayout;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_home,container,false);
//初始化viewpager
viewPager=view.findViewById(R.id.pager);
//初始化tablayout
tableLayout=view.findViewById(R.id.tab);
title.add("华为");
title.add("OPPO");
title.add("ViVO");
title.add("APPLE");
title.add("REDMI");
//初始化fragment的列表
setList();
PagerAdapter adapter=new PagerAdapter(getChildFragmentManager(),list,title);
//设置viewPager缓存的fragment数量,总共缓存(limit*2+1)个,limit就是里面的参数
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(adapter);
//把tableLayout与viewPager绑定
tableLayout.setupWithViewPager(viewPager);
return view;
}
private void setList() {
if (oneFragment==null){
oneFragment=new OneFragment();
list.add(oneFragment);
}
if (twoFragment==null){
twoFragment=new TwoFragment();
list.add(twoFragment);
}
if (threeFragment==null){
threeFragment=new ThreeFragment();
list.add(threeFragment);
}
if (fourFragment==null){
fourFragment=new FourFragment();
list.add(fourFragment);
}
if (fiveFragment==null){
fiveFragment=new FiveFragment();
list.add(fiveFragment);
}
}
}
最后只差Adapter的代码啦,请看下面:
public class PagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragmentArrayList;
private ArrayList<String> title;
public PagerAdapter(FragmentManager fm,ArrayList<Fragment> fragmentArrayList,ArrayList<String> title) {
super(fm);
this.fragmentArrayList=fragmentArrayList;
this.title=title;
}
@Override
public Fragment getItem(int position) {
return fragmentArrayList.get(position);
}
@Override
public int getCount() {
return fragmentArrayList.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return title.get(position);
}
}
这就是今天的所有内容。加油