【Android】ViewPager的使用
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:background="@android:color/white">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
import android.os.Bundle;
import android.util.Log;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
import com.cib.myapplication.adapters.AppFragmentPagerAdapter;
import com.cib.myapplication.fragments.HomeFragment;
import com.cib.myapplication.fragments.MyFragment;
import com.cib.myapplication.fragments.WalletFragment;
import com.cib.myapplication.fragments.WealthFragment;
import com.cib.myapplication.widgets.CustomRadioButton;
import com.cib.myapplication.widgets.CustomViewPager;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public CustomViewPager mViewPager;
private RadioGroup mainTab;
private ArrayList<Fragment> mainFraments = new ArrayList<>();
private ArrayList<RadioButton> tabBars = new ArrayList<>();
public HomeFragment homePageFragment;
public WealthFragment wealthFragment;
public WalletFragment walletFragment;
public MyFragment myFragment;
private AppFragmentPagerAdapter mAdapter;
public static CustomRadioButton homeBar, wealthBar, walletBar, accountBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
//find
mViewPager = findViewById(R.id.activity_content);
mainTab = findViewById(R.id.main_tab_views);
//find tab bar
homeBar = this.findViewById(R.id.bottom_bar_home);
wealthBar = this.findViewById(R.id.bottom_bar_wealth);
walletBar = this.findViewById(R.id.bottom_bar_wallet);
accountBar = this.findViewById(R.id.bottom_bar_account);
tabBars.add(homeBar);
tabBars.add(wealthBar);
tabBars.add(walletBar);
tabBars.add(accountBar);
//view pager
homePageFragment = new HomeFragment();
wealthFragment = new WealthFragment();
walletFragment = new WalletFragment();
myFragment = new MyFragment();
mainFraments.add(homePageFragment);
mainFraments.add(wealthFragment);
mainFraments.add(walletFragment);
mainFraments.add(myFragment);
mAdapter = new AppFragmentPagerAdapter(getSupportFragmentManager(), mainFraments);
mViewPager.setAdapter(mAdapter);
mainTab.setOnCheckedChangeListener((group, checkedId) -> {
int index = group.indexOfChild(group.findViewById(checkedId));
Log.d("'QDLog'", "index " + index);
mViewPager.setCurrentItem(index);
});
ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
int currentItem = mViewPager.getCurrentItem();
tabBars.get(currentItem).setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
mViewPager.addOnPageChangeListener(listener);
}
}
AppFragmentPagerAdapter.java
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import java.util.ArrayList;
import java.util.List;
/**
* 实现Fragment ViewPager适配器,用于App主体4个TAB页滑动切换
*/
public class AppFragmentPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragmentList = new ArrayList<>();
private FragmentManager fm;
public AppFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm);
this.fm = fm;
this.mFragmentList.addAll(fragmentList);
}
@Override
public Fragment getItem(int position) {
return mFragmentList == null ? null : mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList == null ? 0 : mFragmentList.size();
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 保证ViewPager切换过程中,page不会被销毁
// super.destroyItem(container, position, object);
}
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
public void setFragmentList(List<Fragment> fragmentList) {
this.mFragmentList.clear();
this.mFragmentList.addAll(fragmentList);
notifyDataSetChanged();
}
public void clearFragment() {
if (this.mFragmentList != null) {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
for (Fragment f : this.mFragmentList) {
fragmentTransaction.remove(f);
}
fragmentTransaction.commit();
fm.executePendingTransactions();
}
}
}
HomeFragment.java
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.cib.myapplication.R;
public class HomeFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
}
CustomRadioButton.java
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatRadioButton;
import com.cib.myapplication.R;
/**
* 自定义底部Button
*/
public class CustomRadioButton extends AppCompatRadioButton {
private int mDrawableSize; // XML文件中设置的大小
public CustomRadioButton(Context context) {
this(context, null, 0);
}
public CustomRadioButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomRadioButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Drawable drawableLeft = null, drawableTop = null, drawableRight = null, drawableBottom = null;
TypedArray tArray = context.obtainStyledAttributes(attrs, R.styleable.CustomRadioButton);
mDrawableSize = tArray.getDimensionPixelSize(R.styleable.CustomRadioButton_drawablesize, 50);
drawableTop = tArray.getDrawable(R.styleable.CustomRadioButton_drawabletop);
drawableBottom = tArray.getDrawable(R.styleable.CustomRadioButton_drawableBottom);
// int attrCount = tArray.getIndexCount();
// for (int i = 0; i < attrCount; i++) {
// int attr = tArray.getIndex(i);
// switch (attr) {
// case R.styleable.CustomRadioButton_drawablesize:
// mDrawableSize = tArray.getDimensionPixelSize(R.styleable.CustomRadioButton_drawablesize, 50);
Log.d("appfw", "mDrawableSize:" + mDrawableSize);
// break;
// case R.styleable.CustomRadioButton_drawabletop:
// drawableTop = tArray.getDrawable(attr);
// break;
// case R.styleable.CustomRadioButton_drawableBottom:
// drawableBottom = tArray.getDrawable(attr);
// break;
// default:
// break;
// }
// }
tArray.recycle();
setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);
}
public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) {
if (left != null) {
left.setBounds(0, 0, mDrawableSize, mDrawableSize);
}
if (right != null) {
right.setBounds(0, 0, mDrawableSize, mDrawableSize);
}
if (top != null) {
top.setBounds(0, 0, mDrawableSize, mDrawableSize);
}
if (bottom != null) {
bottom.setBounds(0, 0, mDrawableSize, mDrawableSize);
}
setCompoundDrawables(left, top, right, bottom);
}
}
CustomViewPager.java
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.viewpager.widget.ViewPager;
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
try {
return super.onTouchEvent(ev);
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- App5.0为支持划动切换页面变更Content view为ViewPager-->
<com.cib.myapplication.widgets.CustomViewPager
android:id="@+id/activity_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" />
<!-- 自定义标签栏 -->
<include
android:id="@+id/main_tab_views"
layout="@layout/bottom_bar_ver5"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true" />
<RelativeLayout
android:id="@+id/rl_older_layout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true">
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_alignParentBottom="true"
android:layout_marginBottom="55dp"
android:background="@color/devideline_bg" />
</RelativeLayout>
</RelativeLayout>
<!-- <include-->
<!-- layout="@layout/bindkeyboard_num"-->
<!-- android:visibility="gone" />-->
<!-- <com.cib.qdzg.widgets.NumKeyBoard-->
<!-- android:id="@+id/num_keyboard_index"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:visibility="gone" />-->
<!-- <include-->
<!-- layout="@layout/input"-->
<!-- android:visibility="gone" />-->
<!-- <ImageView-->
<!-- android:id="@+id/iv_advertPic"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:visibility="gone" />-->
</FrameLayout>
bottom_bar_ver5.xml
<?xml version="1.0" encoding="utf-8"?>
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:radio="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_tab"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
android:orientation="horizontal">
<com.cib.myapplication.widgets.CustomRadioButton
android:id="@+id/bottom_bar_home"
style="@style/bottom_bar_item"
android:checked="true"
android:text="@string/tabbar_home_title"
radio:drawablesize="20dp"
radio:drawabletop="@drawable/bottom_bar_home_ver5" />
<com.cib.myapplication.widgets.CustomRadioButton
android:id="@+id/bottom_bar_wealth"
style="@style/bottom_bar_item"
android:text="@string/tabbar_wealth_title"
radio:drawablesize="20dp"
radio:drawabletop="@drawable/bottom_bar_wealth_ver5" />
<com.cib.myapplication.widgets.CustomRadioButton
android:id="@+id/bottom_bar_wallet"
style="@style/bottom_bar_item"
android:text="@string/tabbar_wallet_title"
radio:drawablesize="20dp"
radio:drawabletop="@drawable/bottom_bar_wallet_ver5" />
<com.cib.myapplication.widgets.CustomRadioButton
android:id="@+id/bottom_bar_account"
style="@style/bottom_bar_item"
android:text="@string/tabbar_account_title"
radio:drawablesize="20dp"
radio:drawabletop="@drawable/bottom_bar_account_ver5" />
</RadioGroup>
fragment_home.xml,fragment_my.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:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Home Page"
android:textSize="24sp"/>
</LinearLayout>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="bottom_bar_text_normal">#555555</color>
<color name="bottom_bar_text_checked">#5047FF</color>
<color name="transparent">#00000000</color>
<color name="devideline_bg">#E5E5E5</color>
</resources>
strings.xml
<resources>
<string name="app_name">MyApplication</string>
<string name="tabbar_home_title">首页</string>
<string name="tabbar_wealth_title">财富</string>
<string name="tabbar_scan_title">扫一扫</string>
<string name="tabbar_wallet_title">钱包</string>
<string name="tabbar_account_title">我的</string>
</resources>
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomRadioButton">
<attr name="drawablesize" format="dimension" />
<attr name="drawabletop" format="reference" />
<attr name="drawableBottom" format="reference" />
</declare-styleable>
<!-- Bottom start -->
<style name="bottom_bar_item">
<item name="android:textSize">12sp</item>
<item name="android:textColor">@drawable/bottom_bar_text_color</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_weight">1</item>
<item name="android:gravity">center</item>
<item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">5dp</item>
<item name="android:drawablePadding">1.0dip</item>
<item name="android:button">@null</item>
<item name="android:background">@null</item>
<item name="android:clickable">true</item>
</style>
</resources>
themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="BaseTheme">
</style>
<style name="BaseTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowBackground">@drawable/bg_splash_layer</item>
</style>
</resources>
demo download:
demo