ViewPager+RadioGroup实现左右滑动卡片布局

本文实例为大家分享了ViewPager+RadioGroup实现左右滑动卡片布局的具体代码,供大家参考,具体内容如下

效果如图所示:

1.选择某个界面时,对应的第几个小圆点亮:

通过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.主界面内嵌的卡片视图布局:

<?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.卡片布局对应的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;
        }
    }

    /**
     * 初始化数据
     */
    private void initData() {
        switch (position) {
            case 0:
                tvTitle.setText("卡片内容" + "layout_data1");
                chartBar.setBackgroundColor(Color.parseColor("#6ddac6"));
                break;
            case 1:
                tvTitle.setText("卡片内容" + "layout_data2");
                chartBar.setBackgroundColor(getResources().getColor(R.color.app_green_area));
                break;
            case 2:
                tvTitle.setText("卡片内容" + "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());//设置卡片之间切换的样式
        viewPager.setOffscreenPageLimit(3);//限定预加载的卡片个数
        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) {
        //根据监听viewPager的PageChangeListener获得选择的是哪个卡片,并把其对应位序的小圆点设置为选定状态
        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;//卡片个数
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android ViewPager无限循环实现底部小圆点动态滑动

    页面拖动到最后一页 再向下滑动回复到 第一页,第一页向前滑动回到 最后一页 同时,底部红色小圆点随着页面的滑动距离比例随时改变位置 布局: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas

  • Android仿探探卡片式滑动效果实现

    前言 第一次进入探探软件界面,就被这种通过卡片式滑动来选择"喜欢/不喜欢"的设计所吸引了.当时就非常想通过自己来实现这种仿探探式的效果,然而却没什么思路.不过毋庸置疑的是,这种效果的原理肯定和 ListView / RecyclerView 类似,涉及到 Item View 的回收和重用,否则早就因为大量的 Item View 而 OOM 了. 再到后来,看到许多大神也推出了同样仿探探效果的博客,从头到尾阅读下来,写得通俗易懂,基本上没什么问题.于是,实现仿探探效果的想法再次出现在脑海

  • 使用ViewPager实现左右循环滑动及滑动跳转

    前面一篇文章实现了使用ViewPager实现高仿launcher拖动效果 ,后来很多朋友问能不能实现左右循环滑动效果和引导页面.今天实现了左右滑动,至于在最后一页滑动跳转,这个也做了但是效果不是太好,也希望有实现的朋友能够分享下.在最后一页添加一张图片单击跳转,这个认为很简单大家自己添加个图片,点击后跳转就OK. 这篇是在实现了使用ViewPager实现高仿launcher拖动效果的基础上做了一些小的修改,可以参照前面的.废话不多说了,直接上代码吧! 首先看一些layout下的xml 复制代码

  • Android实现横向滑动卡片效果

    最近项目上需要实现这样效果的一个页面,本来想找个现成的两下搞定,但是问了半天度娘也没招,索性自己琢磨琢磨(这里边也少不了同事的帮助),先把最终的效果图贴上: 理论上讲,其本质并不复杂,就是一个viewpager,但是第一次实现这样的效果还是要花些时间的,具体的代码如下: 主布局文件:activity_show_industry_list.xml,主要就是一个activity上放个viewpager,但是相对布局是关键 <?xml version="1.0" encoding=&q

  • Android利用ViewPager实现滑动广告板实例源码

    •android-support-v4.jar,这是谷歌官方给我们提供的一个兼容低版本Android设备的软件包,里面包囊了只有在Android3.0以上可以使用的api.而ViewPager就是其中之一,利用它我们可以做很多事情,从最简单的导航,到页面切换菜单等等. •ViewPager的功能就是可以使视图滑动,就像Lanucher左右滑动那样. •本Demo向大家演示ViewPager的使用,并在用户未滑动View时,每隔5s钟自动切换到下一个View(循环切换),而当用户有Touch到Vi

  • Android开发之使用ViewPager实现图片左右滑动切换效果

    Android中图片的左右切换随处可见,今天我也试着查阅资料试着做了一下,挺简单的一个小Demo,却也发现了一些问题,话不多说,上代码~: 使用了3个xml文件作为ViewPager的滑动page,布局都是相同的,如下只展示其中之一: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/

  • 自定义RadioButton和ViewPager实现TabHost带滑动的页卡效果

    在工作中又很多需求都不是android系统自带的控件可以达到效果的,内置的TabHost就是,只能达到简单的效果 ,所以这个时候就要自定义控件来达到效果:这个效果就是: 使用自定义RadioButton和ViewPager实现TabHost带滑动的页卡效果. 这篇文章技术含量一般,大家别见笑.源码我以测试,在底部可下载.好了先上效果图: 以下是实现步骤:        1.准备自定义RadioButton控件的样式图片等,就是准备配置文件: (1). 在项目的values文件夹里面创建 attr

  • Android中ViewPager带来的滑动卡顿问题解决要点解析

    问题说明: 当SwipeRefreshLayout中放置了ViewPager控件,两者的滑动会相互冲突.具体表现为ViewPager的左右滑动不顺畅,容易被SwipeRefreshLayout拦截(即出现刷新的View). 问题原因: ViewPager本身是处理了滚动事件的冲突,它在横向滑动时会调用requestDisallowInterceptTouchEvent()方法使父控件不拦截当前的Touch事件序列.但是SwipeRefreshLayout的requestDisallowInter

  • Android App中使用ViewPager+Fragment实现滑动切换效果

    在android应用中,多屏滑动是一种很常见的风格,没有采用viewpager的代码实现会很长,如果采用ViewPager,代码就会短很多,但是使用ViewPager也有弊端:需要导入android-support-v4.jar.细节无法控制.不过现在情况已经不一样了,android-support-v4中提供了很多实用的功能,以至于现在新建一个android工程默认都会导入这个jar包.那我们就也采用viewpager来做滑动吧.另外一个概念就是Fragment和FragmentActivit

  • Android App中ViewPager所带来的滑动冲突问题解决方法

    叙述 滑动冲突可以说是日常开发中比较常见的一类问题,也是比较让人头疼的一类问题,尤其是在使用第三方框架的时候,两个原本完美的控件,组合在一起之后,忽然发现整个世界都不好了. 关于滑动冲突 滑动冲突分类: 滑动冲突,总的来说就是两类. 1.同方向滑动冲突 比如ScrollView嵌套ListView,或者是ScrollView嵌套自己 2.不同方向滑动冲突 比如ScrollView嵌套ViewPager,或者是ViewPager嵌套ScrollView,这种情况其实很典型.现在大部分应用最外层都是

随机推荐