Previous results:
There are two problems in this project:
1. State when ImageView uses mixed images_ The checked attribute setSelected(true) is invalid in the code. The specific reason is not found
So I used state_ This attribute is replaced by pressed
However, there was another problem. Pressing the button would change color. After releasing the button, it bounced back to the original color, so I changed the click event to touch event
In this way, the touch can directly capture the state.
2.text discoloration fails when setTextcolor(R.color.xxx) is used
The reason is that setTextcolor accepts hexadecimal data instead of resource id. if you want to use it, you need to call the getColor method
Well, don't say much. Let's start the text
·Add the viewpager2 control in the activity (the old sdk may need to add the corresponding control package in build.gradle)
·Prepare eight pictures( Alibaba vector icon library ), create four groups of picture resource files in drawable (click to change the picture background)
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/faxian_on" android:state_pressed="true"/> <item android:drawable="@drawable/faxian" /> </selector>
·Create navigation bar
<?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="horizontal"> <LinearLayout android:id="@+id/weixin" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> //Add a mixed picture_ fix <ImageView android:id="@+id/weixin_button" android:layout_gravity="center_horizontal" android:background="@drawable/weixinliaotian_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text="WeChat" android:id="@+id/t1" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:id="@+id/tongxunlu" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <ImageView android:id="@+id/tongxunlu_button" android:layout_gravity="center_horizontal" android:background="@drawable/tongxunlu_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/t2" android:layout_gravity="center_horizontal" android:text="mail list" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:id="@+id/faxian" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <ImageView android:id="@+id/faxian_button" android:layout_gravity="center_horizontal" android:background="@drawable/faxian_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/t3" android:layout_gravity="center_horizontal" android:text="find" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:id="@+id/wode" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <ImageView android:id="@+id/wode_button" android:layout_gravity="center_horizontal" android:background="@drawable/wode_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/t4" android:layout_gravity="center_horizontal" android:text="I" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
·Introducing the navigation bar in the activity interface
·Get the viewpager2 object in the activity and set the adapter
viewPager2 = findViewById(R.id.vp2); viewpageradapter = new viewpageradapter(getSupportFragmentManager(), getLifecycle(), fragmentList); viewPager2.setAdapter(viewpageradapter);
·Create a fragment (there is only one text control)
·Create adapter (inheriting FragmentStateAdapter instead of FragmentPagerAdapter)
Differences between FragmentPageAdapter and FragmentPageStateAdapter:
The FragmentPageAdapter separates fragments every time it switches pages. It is suitable for fragments with fewer pages to save some memory, which will not have much impact on the system memory
The FragmentPageStateAdapter recycles fragments every time a page is switched. It is suitable for fragments with more pages, so it will not consume more memory
public class viewpageradapter extends FragmentStateAdapter { //Receive fragment List<Fragment> fragmentList; public viewpageradapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle,List<Fragment> fragmentList) { super(fragmentManager, lifecycle); this.fragmentList=fragmentList; } @NonNull @Override public Fragment createFragment(int position) { //Return to the fragment interface of the corresponding position return fragmentList.get(position); } @Override public int getItemCount() { //Returns the number of fragment s return fragmentList.size(); } }
·The key point is to realize the linkage effect of fragment and navigation bar buttons
To use this callback function: to implement three methods, all we need to implement is the method of changing the page
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { /** * This method is responsible for listening for page offsets * @param position The position index of the first page currently displayed. If positionOffset is non-zero, the page position + 1 will be visible. * @param positionOffset [0, 1) The value in indicates the offset from the page position. * @param positionOffsetPixels A value in pixels indicating the offset from the position. */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { super.onPageScrolled(position, positionOffset, positionOffsetPixels); } //Solve the version problem of getcolor (can be deleted) @RequiresApi(api = Build.VERSION_CODES.M) //This method is responsible for switching the page, and the position starts from 0 @Override public void onPageSelected(int position) { changetab(position); } //Called when the scrolling state changes. It is used to find out when the user starts dragging, when to start pseudo dragging, when the pager automatically stabilizes to the current page, or when to stop / idle completely. @Override public void onPageScrollStateChanged(int state) { super.onPageScrollStateChanged(state); } }); }
This is the trigger method of the button touch event
@RequiresApi(api = Build.VERSION_CODES.M) @Override public boolean onTouch(View view, MotionEvent motionEvent) { changetab(view.getId()); return false; }
This method is responsible for receiving two different parameters: the current scroll page position and the button id
The page scroll call button is set to the pressed state, and the button is pressed to scroll the page to the corresponding page, so as to realize the linkage effect.
//The above two references are used to set the text color @RequiresApi(api = Build.VERSION_CODES.M) @SuppressLint("ResourceAsColor") private void changetab(int position) { //Set the pressing state to false and the text color to the initial color before each scroll current.setPressed(false); currenttext.setTextColor(MainActivity.this.getColor(black)); switch (position) { case R.id.weixin: //The reason why the button id passed in does not need to save the current state / color is that the page scrolling will automatically call the callback function to trigger the above three methods, that is, the changetab method will be called again, but the corresponding position value will be passed in viewPager2.setCurrentItem(0); break; case 0: //Set text color t1.setTextColor(MainActivity.this.getColor(green)); //Set imageview to pressed state weixin_button.setPressed(true); //Save current status / color current = weixin_button; currenttext = t1; break; case R.id.tongxunlu: viewPager2.setCurrentItem(1); break; case 1: t2.setTextColor(MainActivity.this.getColor(green)); tongxunlu_button.setPressed(true); current = tongxunlu_button; currenttext = t2; break; case R.id.faxian: viewPager2.setCurrentItem(2); break; case 2: t3.setTextColor(MainActivity.this.getColor(green)); faxian_button.setPressed(true); current = faxian_button; currenttext = t3; break; case R.id.wode: viewPager2.setCurrentItem(3); break; case 3: t4.setTextColor(MainActivity.this.getColor(green)); wode_button.setPressed(true); current = wode_button; currenttext = t4; break; } }
The source code is as follows:
Maintivity
public class MainActivity extends AppCompatActivity implements View.OnTouchListener { List<Fragment> fragmentList;//The fragment collection passes parameters to the adapter viewpageradapter viewpageradapter; ViewPager2 viewPager2; LinearLayout weixin, tongxunlu, faxian, wode; ImageView weixin_button, tongxunlu_button, faxian_button, wode_button, current;//Current records the current imageview status TextView t1, t2, t3, t4, currenttext;//currenttext records the current text status @RequiresApi(api = Build.VERSION_CODES.M) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); weixin.setOnTouchListener(this); tongxunlu.setOnTouchListener(this); faxian.setOnTouchListener(this); wode.setOnTouchListener(this); viewPager2 = findViewById(R.id.vp2); viewpageradapter = new viewpageradapter(getSupportFragmentManager(), getLifecycle(), fragmentList); viewPager2.setAdapter(viewpageradapter); viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { super.onPageScrolled(position, positionOffset, positionOffsetPixels); } @RequiresApi(api = Build.VERSION_CODES.M) @Override public void onPageSelected(int position) { changetab(position); } @Override public void onPageScrollStateChanged(int state) { super.onPageScrollStateChanged(state); } }); } @RequiresApi(api = Build.VERSION_CODES.M) @SuppressLint("ResourceAsColor") private void changetab(int position) { current.setPressed(false); currenttext.setTextColor(MainActivity.this.getColor(black)); switch (position) { case R.id.weixin: viewPager2.setCurrentItem(0); Log.d("TAG", "changetab:weixin Press " + weixin_button.isPressed()); break; case 0: t1.setTextColor(MainActivity.this.getColor(green)); weixin_button.setPressed(true); Log.d("TAG", "changetab:weixin slide " + weixin_button.isPressed()); current = weixin_button; currenttext = t1; break; case R.id.tongxunlu: viewPager2.setCurrentItem(1); Log.d("TAG", "changetab:tongxunlu Press " + tongxunlu_button.isPressed()); break; case 1: t2.setTextColor(MainActivity.this.getColor(green)); tongxunlu_button.setPressed(true); Log.d("TAG", "changetab:tongxunlu slide " + tongxunlu.isPressed()); current = tongxunlu_button; currenttext = t2; break; case R.id.faxian: viewPager2.setCurrentItem(2); Log.d("TAG", "changetab:faxian Press " + faxian_button.isPressed()); break; case 2: t3.setTextColor(MainActivity.this.getColor(green)); faxian_button.setPressed(true); Log.d("TAG", "changetab:faxian slide " + faxian_button.isPressed()); current = faxian_button; currenttext = t3; break; case R.id.wode: viewPager2.setCurrentItem(3); Log.d("TAG", "changetab:wode Press " + wode_button.isPressed()); break; case 3: t4.setTextColor(MainActivity.this.getColor(green)); wode_button.setPressed(true); Log.d("TAG", "changetab:wode slide " + wode_button.isPressed()); current = wode_button; currenttext = t4; break; } } @RequiresApi(api = Build.VERSION_CODES.M) @SuppressLint("ResourceAsColor") private void init() { fragmentList = new ArrayList<>(); fragmentList.add(BlankFragment.newInstance("WeChat")); fragmentList.add(BlankFragment.newInstance("contacts")); fragmentList.add(BlankFragment.newInstance("find")); fragmentList.add(BlankFragment.newInstance("my")); weixin = findViewById(R.id.weixin); tongxunlu = findViewById(R.id.tongxunlu); faxian = findViewById(R.id.faxian); wode = findViewById(R.id.wode); weixin_button = findViewById(R.id.weixin_button); tongxunlu_button = findViewById(R.id.tongxunlu_button); faxian_button = findViewById(R.id.faxian_button); wode_button = findViewById(R.id.wode_button); t1 = findViewById(R.id.t1); t2 = findViewById(R.id.t2); t3 = findViewById(R.id.t3); t4 = findViewById(R.id.t4); weixin_button.setPressed(true); t1.setTextColor(MainActivity.this.getColor(green)); current = weixin_button; currenttext = t1; } @RequiresApi(api = Build.VERSION_CODES.M) @Override public boolean onTouch(View view, MotionEvent motionEvent) { changetab(view.getId()); return false; } }
Maintivity layout
<?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" android:orientation="vertical" tools:context=".MainActivity"> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/vp2" android:layout_height="0dp" android:layout_weight="11" android:layout_width="match_parent"/> <include layout="@layout/navigation" android:layout_height="0dp" android:layout_weight="1" android:layout_width="match_parent"/> </LinearLayout>
viewpagerAdapter
public class viewpageradapter extends FragmentStateAdapter { List<Fragment> fragmentList; public viewpageradapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle,List<Fragment> fragmentList) { super(fragmentManager, lifecycle); this.fragmentList=fragmentList; } @NonNull @Override public Fragment createFragment(int position) { return fragmentList.get(position); } @Override public int getItemCount() { return fragmentList.size(); } }
viewpagerAdapter layout
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".BlankFragment"> <TextView android:id="@+id/ft1" android:text="nice" android:layout_centerInParent="true" android:textSize="50sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> **navigation(Layout only)** <?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="horizontal"> <LinearLayout android:id="@+id/weixin" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <ImageView android:id="@+id/weixin_button" android:layout_gravity="center_horizontal" android:background="@drawable/weixinliaotian_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text="WeChat" android:id="@+id/t1" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:id="@+id/tongxunlu" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <ImageView android:id="@+id/tongxunlu_button" android:layout_gravity="center_horizontal" android:background="@drawable/tongxunlu_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/t2" android:layout_gravity="center_horizontal" android:text="mail list" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:id="@+id/faxian" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <ImageView android:id="@+id/faxian_button" android:layout_gravity="center_horizontal" android:background="@drawable/faxian_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/t3" android:layout_gravity="center_horizontal" android:text="find" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:id="@+id/wode" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <ImageView android:id="@+id/wode_button" android:layout_gravity="center_horizontal" android:background="@drawable/wode_fix" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/t4" android:layout_gravity="center_horizontal" android:text="I" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
The picture and color are gone