Android實現(xiàn)界面內(nèi)嵌多種卡片視圖(ViewPager、RadioGroup)
Android實現(xiàn)界面內(nèi)嵌多種卡片視圖,具體內(nèi)容如下
效果如圖所示:


1.選擇某個界面時,對應(yīng)的第幾個小圓點亮:
通過selector制造圓點和進行更改小圓點被選擇和未被選擇時的顏色:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true"> <shape> <solid android:color="@color/app_green_area" /> <corners android:radius="5dp" /> </shape> </item> <item android:state_checked="false"> <shape> <solid android:color="#fff" /> <corners android:radius="5dp" /> <stroke android:width="0.2dp" android:color="@color/app_line"/> </shape> </item> </selector>
2.主界面布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" android:background="@color/app_gray_bg"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textSize="25sp" android:textColor="@color/colorPrimary" android:text="health頁面"/> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_gravity="center" android:overScrollMode="never" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <RadioGroup android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:id="@+id/group" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:orientation="horizontal"> <RadioButton android:layout_width="10dp" android:layout_height="10dp" android:layout_marginLeft="10dp" android:background="@drawable/selector_point" android:button="@null" /> <RadioButton android:layout_width="10dp" android:layout_height="10dp" android:layout_marginLeft="10dp" android:background="@drawable/selector_point" android:button="@null" /> <RadioButton android:layout_width="10dp" android:layout_height="10dp" android:layout_marginLeft="10dp" android:background="@drawable/selector_point" android:button="@null" /> </RadioGroup> </RelativeLayout>

3.主界面內(nèi)嵌的卡片視圖布局:
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="2dp" app:cardCornerRadius="8dp"> <LinearLayout android:id="@+id/chart_bar" android:adjustViewBounds="true" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_title" android:textColor="@color/app_black" android:gravity="center" android:textSize="30sp" android:layout_width="match_parent" android:layout_height="wrap_content" /> <LinearLayout android:adjustViewBounds="true" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/layout_data1" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:visibility="visible" android:orientation="vertical"> <TextView android:text="layout_data1" android:textSize="30sp" android:textColor="@color/colorPrimary" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:id="@+id/layout_data2" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:visibility="visible" android:orientation="vertical"> <TextView android:text="layout_data2" android:textSize="30sp" android:textColor="@color/colorPrimary" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:id="@+id/layout_data3" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:visibility="visible" android:orientation="vertical"> <TextView android:text="layout_data3" android:textSize="30sp" android:textColor="@color/colorPrimary" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> </LinearLayout> </android.support.v7.widget.CardView>
4.定義卡片之間切換的樣式:
/**
* 卡片之間切換的樣式
*/
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
public static final float MAX_SCALE = 0.9f;
public static final float MIN_SCALE = 0.8f;
@Override
public void transformPage(View page, float position) {
position = position < -1 ? -1 : position;
position = position > 1 ? 1 : position;
float tempScale = position < 0 ? 1 + position : 1 - position;
float slope = (MAX_SCALE - MIN_SCALE) / 1;
float scaleValue = MIN_SCALE + tempScale * slope;
page.setScaleX(scaleValue);
page.setScaleY(scaleValue);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
page.getParent().requestLayout();
}
}
}
5.定義用于加載卡片視圖的layout控件,方便自定義寬高比例:
import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
/**
* 用于加載卡片視圖
*/
public class RatioLayout extends ViewGroup {
private float heightWidthRatio = 0.325f;
public RatioLayout(Context context) {
this(context, null);
}
public RatioLayout(Context context, AttributeSet attrs) {
super(context, attrs);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.RatioLayout);
heightWidthRatio = getFloatFromString(a.getString(R.styleable.RatioLayout_height_width_ratio));
a.recycle();
}
public void setHeightWidthRatio(String ratio) {
heightWidthRatio = getFloatFromString(ratio);
}
public static float getFloatFromString(String src) {
if (TextUtils.isEmpty(src)) {
return 0;
}
float result;
try {
result = Float.parseFloat(src);
return result;
} catch (Exception e) {
}
String[] strs = src.split("/");
if (strs.length == 2) {
try {
float molecular = Float.parseFloat(strs[0]);//分子
float denominator = Float.parseFloat(strs[1]);//分子
result = molecular / denominator;
} catch (Exception e) {
result = 0;
}
} else {
result = 0;
}
return result;
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
layoutChildren(left, top, right, bottom);
}
void layoutChildren(int left, int top, int right, int bottom) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final LayoutParams lp = child.getLayoutParams();
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
child.layout(0, 0, width, 0 + height);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (heightWidthRatio > 0) {
int width = getMeasuredWidth();
int height = (int) (width * heightWidthRatio);
setMeasuredDimension(width, height);
int count = getChildCount();
if (count >= 1) {
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
child.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
}
}
}
}
}
6.卡片布局對應(yīng)的activity:
public class FrHealthChart extends Fragment {
public static final String DATA = "_data";
@BindView(R.id.layout_data1)
LinearLayout layoutData1;
@BindView(R.id.layout_data2)
LinearLayout layoutData2;
@BindView(R.id.layout_data3)
LinearLayout layoutData3;
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.chart_bar)
LinearLayout chartBar;
private int position;//用于標識選擇的是哪個layout
public static Fragment getInstance(int position) {
FrHealthChart frHealthChart = new FrHealthChart();
Bundle bundle = new Bundle();
bundle.putInt(DATA, position);
frHealthChart.setArguments(bundle);
return frHealthChart;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.from(getContext()).inflate(R.layout.fragment_health_chart, container, false);
ButterKnife.bind(this, view);
Bundle bundle = getArguments();
if (bundle != null) {
position = bundle.getInt(DATA);
initCard();
}
//加載卡片視圖,控制寬高比例
RatioLayout ratioLayout = new RatioLayout(getContext());
ratioLayout.addView(view);
ratioLayout.setHeightWidthRatio("67/52");
return ratioLayout;
}
private void initCard() {
switch (position) {
case 0://顯示layoutData1
layoutData1.setVisibility(View.VISIBLE);
layoutData2.setVisibility(View.GONE);
layoutData3.setVisibility(View.GONE);
initData();
break;
case 1://顯示layoutData2
layoutData1.setVisibility(View.GONE);
layoutData2.setVisibility(View.VISIBLE);
layoutData3.setVisibility(View.GONE);
initData();
break;
case 2://顯示layoutData3
layoutData1.setVisibility(View.GONE);
layoutData2.setVisibility(View.GONE);
layoutData3.setVisibility(View.VISIBLE);
initData();
break;
}
}
/**
* 初始化數(shù)據(jù)
*/
private void initData() {
switch (position) {
case 0:
tvTitle.setText("卡片內(nèi)容" + "layout_data1");
chartBar.setBackgroundColor(Color.parseColor("#6ddac6"));
break;
case 1:
tvTitle.setText("卡片內(nèi)容" + "layout_data2");
chartBar.setBackgroundColor(getResources().getColor(R.color.app_green_area));
break;
case 2:
tvTitle.setText("卡片內(nèi)容" + "layout_data3");
chartBar.setBackgroundColor(getResources().getColor(R.color.colorAccent));
break;
}
}
}
7.主界面的activity代碼:
public class FrHealth extends Fragment implements ViewPager.OnPageChangeListener {
@BindView(R.id.view_pager)
ViewPager viewPager;
@BindView(R.id.group)
RadioGroup group;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_health, container, false);
ButterKnife.bind(this, view);
initView();
return view;
}
private void initView() {
RadioButton childAt = (RadioButton) group.getChildAt(0);
childAt.setChecked(true);
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());//設(shè)置卡片之間切換的樣式
viewPager.setOffscreenPageLimit(3);//限定預加載的卡片個數(shù)
ViewGroup.LayoutParams layoutParams = viewPager.getLayoutParams();
// layoutParams.height = AppUtil.dp2px(getContext(), 400);
float scale = getContext().getResources().getDisplayMetrics().density;
layoutParams.height = (int) (400 * scale + 0.5F);//計算高寬
layoutParams.width = (int) (layoutParams.height * 0.8);
if (viewPager.getParent() instanceof ViewGroup) {
ViewGroup viewParent = ((ViewGroup) viewPager.getParent());
viewParent.setClipChildren(false);
viewPager.setClipChildren(false);
}
viewPager.addOnPageChangeListener(this);
MyPagerAdapter myPagerAdapter = new MyPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(myPagerAdapter);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//根據(jù)監(jiān)聽viewPager的PageChangeListener獲得選擇的是哪個卡片,并把其對應(yīng)位序的小圓點設(shè)置為選定狀態(tài)
RadioButton childAt = (RadioButton) group.getChildAt(position);
childAt.setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
class MyPagerAdapter extends FragmentPagerAdapter {
HashMap<Integer, Fragment> map = new HashMap<>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
FrHealthChart fragment = (FrHealthChart) map.get(position);
if (fragment == null) {
fragment = (FrHealthChart) FrHealthChart.getInstance(position);
map.put(position, fragment);
}
return fragment;
}
@Override
public int getCount() {
return 3;//卡片個數(shù)
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Android控件系列之RadioButton與RadioGroup使用方法
- android RadioGroup的使用方法
- android自定義RadioGroup可以添加多種布局的實現(xiàn)方法
- Android程序開發(fā)中單選按鈕(RadioGroup)的使用詳解
- Android開發(fā)之RadioGroup的簡單使用與監(jiān)聽示例
- Android RadioGroup和RadioButton控件簡單用法示例
- Android RadioGroup 設(shè)置某一個選中或者不可選中的方法
- Android使用RadioGroup實現(xiàn)底部導航欄
- Android 自定義View實現(xiàn)任意布局的RadioGroup效果
- Android基礎(chǔ)控件RadioGroup使用方法詳解
相關(guān)文章
Compose自定義View實現(xiàn)繪制Rainbow運動三環(huán)效果
這篇文章主要為大家介紹了一個基于Compose自定義的一個Rainbow彩虹運動三環(huán),業(yè)務(wù)上類似于iWatch上的那個運動三環(huán),感興趣的小伙伴可以了解一下2023-02-02
Android中兩個Activity之間數(shù)據(jù)傳遞及返回問題
本篇文章主要介紹了Android中兩個Activity之間數(shù)據(jù)傳遞及返回問題,這里整理了詳細的代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-02-02
Android App開發(fā)中Gradle構(gòu)建過程的配置方法
這篇文章主要介紹了Android App開發(fā)中Gradle構(gòu)建過程的配置方法,包括在Gradle中配置manifest的方法,需要的朋友可以參考下2016-06-06
使用ViewPager實現(xiàn)高仿launcher左右拖動效果
今天用ViewPager這個類實現(xiàn)了同樣的左右拖動效果,這樣代碼更少,但是效果是一樣的,ViewPager是實現(xiàn)左右兩個屏幕平滑地切換的一個類,它是Google提供的,有需要的朋友可以了解下2013-01-01

