**
前端布局
**
- 整体碎片的布局
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<include layout="@layout/Top_tab"/>
<ImageView
android:id="@+id/iv_leng"
android:layout_width="50dp"
android:layout_height="5dp"
android:background="@drawable/shape_bar" />
<!-- ViewPager-->
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_container"
android:layout_weight="1.0"
android:layout_width="match_parent"
android:layout_height="0dp"/>
</LinearLayout>
- 顶部导航栏布局Top_tab.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="wrap_content"
android:orientation="horizontal"
android:paddingTop="3dp"
android:layout_marginBottom="3dp">
<LinearLayout
android:id="@+id/tab1"
android:orientation="vertical"
android:gravity="center"
android:layout_weight="1.0"
android:layout_width="0dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/tab1_iv"
android:background="@drawable/life"
android:layout_width="22dp"
android:layout_height="22dp"/>
<TextView
android:id="@+id/tab1_tv"
android:textSize="13sp"
android:text="@string/btn_2_1"
android:layout_marginTop="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@drawable/select_color_2"/>
</LinearLayout>
<LinearLayout
android:id="@+id/tab2"
android:orientation="vertical"
android:gravity="center"
android:layout_weight="1.0"
android:layout_width="0dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/tab2_iv"
android:background="@drawable/exercise"
android:layout_width="22dp"
android:layout_height="22dp"/>
<TextView
android:id="@+id/tab2_tv"
android:text="@string/btn_2_2"
android:textColor="@drawable/select_color_2"
android:layout_marginTop="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:id="@+id/tab3"
android:orientation="vertical"
android:gravity="center"
android:layout_weight="1.0"
android:layout_width="0dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/tab3_iv"
android:background="@drawable/eat"
android:layout_width="22dp"
android:layout_height="22dp"/>
<TextView
android:id="@+id/tab3_tv"
android:text="@string/btn_2_3"
android:textSize="13sp"
android:layout_marginTop="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@drawable/select_color_2"/>
</LinearLayout>
<LinearLayout
android:id="@+id/tab4"
android:orientation="vertical"
android:gravity="center"
android:layout_weight="1.0"
android:layout_width="0dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/tab4_iv"
android:background="@drawable/weather"
android:layout_width="22dp"
android:layout_height="22dp"/>
<TextView
android:id="@+id/tab4_tv"
android:text="@string/btn_2_4"
android:textSize="13sp"
android:layout_marginTop="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@drawable/select_color_2"/>
</LinearLayout>
</LinearLayout>
- 给导航按钮的selector选择器(以第一个按钮为例)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="false" android:drawable="@mipmap/life_uncheak" />
<item android:state_selected="true" android:drawable="@mipmap/life_cheak"/>
</selector>
后端代码
先创一个继承自FragmentStateAdapter的MyFragmentAdapter类,用来实现对碎片的管理
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
import java.util.List;
public class MyFragmentAdapter extends FragmentStateAdapter {
List<Fragment> list = new ArrayList<>();
public MyFragmentAdapter( FragmentManager fragmentManager, Lifecycle lifecycle , List<Fragment> list) {
super(fragmentManager, lifecycle);
this.list = list;
}
@Override
public Fragment createFragment(int position) {
return list.get(position);
}
@Override
public int getItemCount() {
return list.size();
}
}
然后到主程序中将要用到的控件定义好
private ViewPager2 viewPager;//视图翻页工具,提供了多页面切换的效果。
private LinearLayout tab1,tab2,tab3,tab4;//顶部框四个选择"按钮"(实际只是图片)所在的小布局,给这些布局加点击事件,实现点击效果
private ImageView tab1_iv,tab2_iv,tab3_iv,tab4_iv,current_iv;//四个点击区的图片
private ImageView iv_leng;//导航栏下小长方形条,随着点击移动
private TextView tab1_tv,tab2_tv,tab3_tv,tab4_tv,current_tv;//四个点击区的图片下的文字
private View view;//全局的view最后在onCreateView()里要返回,但要在onCreateView()外面通过要view实现对控件的实例化,只能先拿出来,变成全局变量。
在initView()中实例化:
private void initView() {
tab1 = view.findViewById(R.id.tab1);
tab2 = view.findViewById(R.id.tab2);
tab3 = view.findViewById(R.id.tab3);
tab4 = view.findViewById(R.id.tab4);
tab1_iv = view.findViewById(R.id.tab1_iv);
tab2_iv = view.findViewById(R.id.tab2_iv);
tab3_iv = view.findViewById(R.id.tab3_iv);
tab4_iv = view.findViewById(R.id.tab4_iv);
tab1_tv = view.findViewById(R.id.tab1_tv);
tab2_tv = view.findViewById(R.id.tab2_tv);
tab3_tv = view.findViewById(R.id.tab3_tv);
tab4_tv = view.findViewById(R.id.tab4_tv);
iv_leng=view.findViewById(R.id.iv_leng);
tab1_iv.setSelected(true);
current_iv = tab1_iv;
tab1_tv.setSelected(true);
current_tv = tab1_tv;
tab1.setOnClickListener(this);
tab2.setOnClickListener(this);
tab3.setOnClickListener(this);
tab4.setOnClickListener(this);
viewPager = view.findViewById(R.id.vp_container);
}
在函数中将碎片与viewPager绑定并监听viewPager的滑动
private void initPager() {
//Fragment
List<Fragment> list = new ArrayList<>();
//四个按钮对应的碎片
list.add(new fragment1());
list.add(new fragment2());
list.add(new fragment3());
list.add(new fragment4());
MyFragmentAdapter myFragmentAdapter = new MyFragmentAdapter(getFragmentManager(),getLifecycle(),list);
viewPager.setAdapter(myFragmentAdapter);
// ViewPager2提供的滑动监听
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
pageChage(position);//根据滑动改变按钮的选中状态。
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.d("positionOffset", ""+positionOffset);
Log.d("position", ""+position);
onMoveLeng(position, positionOffset);//顶部导航栏下的小横条,随着按钮的选择而移动
}
});
}
·
·
·
下面的两个pageChage()和selectChange()函数,用来实现对按钮的选中状体做出调整和具体实现的代码,有点冗长,没需求可以跳过。
·
·
·
pageChage()函数,根据viewpaper的切换,对按钮的选中状体做出调整
private void pageChage(int position) {
current_iv.setSelected(false);
current_tv.setSelected(false);
switch (position){
case 0:
selectChange(tab1_iv);
break;
case 1:
selectChange(tab2_iv);
break;
case 2:
selectChange(tab3_iv);
break;
case 3:
selectChange(tab4_iv);
break;
}
}
selectChange()函数,具体调整的实现
private void selectChange(ImageView imageView){
if(imageView==tab1_iv){
//设置图片的选中和未选择
tab1_iv.setSelected(true);
tab2_iv.setSelected(false);
tab3_iv.setSelected(false);
tab4_iv.setSelected(false);
//设置文字颜色的选中和未选择
tab1_tv.setSelected(true);
tab2_tv.setSelected(false);
tab3_tv.setSelected(false);
tab4_tv.setSelected(false);
//设置文字大小的选中和未选择
tab1_tv.setTextSize(18);
tab2_tv.setTextSize(13);
tab3_tv.setTextSize(13);
tab4_tv.setTextSize(13);
}else if(imageView==tab2_iv){
tab1_iv.setSelected(false);
tab2_iv.setSelected(true);
tab3_iv.setSelected(false);
tab4_iv.setSelected(false);
tab1_tv.setSelected(false);
tab2_tv.setSelected(true);
tab3_tv.setSelected(false);
tab4_tv.setSelected(false);
tab1_tv.setTextSize(13);
tab2_tv.setTextSize(18);
tab3_tv.setTextSize(13);
tab4_tv.setTextSize(13);
}else if(imageView==tab3_iv){
tab1_iv.setSelected(false);
tab2_iv.setSelected(false);
tab3_iv.setSelected(true);
tab4_iv.setSelected(false);
tab1_tv.setSelected(false);
tab2_tv.setSelected(false);
tab3_tv.setSelected(true);
tab4_tv.setSelected(false);
tab1_tv.setTextSize(13);
tab2_tv.setTextSize(13);
tab3_tv.setTextSize(18);
tab4_tv.setTextSize(13);
}else if(imageView==tab4_iv){
tab1_iv.setSelected(false);
tab2_iv.setSelected(false);
tab3_iv.setSelected(false);
tab4_iv.setSelected(true);
tab1_tv.setSelected(false);
tab2_tv.setSelected(false);
tab3_tv.setSelected(false);
tab4_tv.setSelected(true);
tab1_tv.setTextSize(13);
tab2_tv.setTextSize(13);
tab3_tv.setTextSize(13);
tab4_tv.setTextSize(18);
}
}
onMoveLeng()函数,用来实现随着按钮的选择,按钮下的小条形框随之移动。(这个我也不太会,这些具体的值都是我调出来的,可能换个屏幕大小不一样的手机就不适用了。)
public float p;//
public void onMoveLeng(int i, float positionOffset) {
p=i+positionOffset;
int left = -10;
int width = 140;
//横线的移动距离
int move = (int) (left + (width - iv_leng.getWidth() / 2) + (p * width * 2));
iv_leng.setTranslationX(move);
}
onCreateView()代码
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_research,container,false);
initView();
initPager();
return view;
}
效果展示
2.
3.
4.
如果要在Activity活动中实现这个效果,也是一样的。