Android使用ViewPagerIndicator、RecyclerView搭建UI

本文详细介绍了如何利用 ViewPagerIndicator、RecyclerView 和 CardView 这些 Android 开发中常用的控件,通过示例代码展示了它们的使用方法,构建了一个具有动态切换选项卡和高效展示数据的 UI。此外,文章还涵盖了 SwipeRefreshLayout 的集成、自定义样式设定及 ItemFragment 的实现,提供了一个完整的项目案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近有个新项目,还没有着手做,目前在熟悉阶段。看完设计稿之后,思考了一阵子,决定使用ViewPagerIndicatorRecyclerView,配合CardView来搭建基本UI。于是便做了下面这个例子,以便了解这些控件的使用,为后面项目做准备。


ViewPagerIndicator是JakeWharton大神开源出来的库,点击传送项目地址
首先将代码下载下来后,会有library、sample2个文件夹。library是库工程,sample是演示工程。若我们要在自己的项目中使用ViewPagerIndicator,则需要依赖library工程。
ViewPagerIndicator由于可以自定义Theme,所以不能使用gradle直接依赖。本例中的自定义Style如下:

<style name="StyledIndicators" parent="@android:style/Theme.Light">
        <item name="vpiTabPageIndicatorStyle">@style/CustomTabPageIndicator</item>
    </style>

    <style name="CustomTabPageIndicator" parent="Widget.TabPageIndicator">
        <item name="android:background">@drawable/tab_indicator</item>
        <item name="android:textAppearance">@style/CustomTabPageIndicator.Text</item>
        <item name="android:textSize">14sp</item>
        <item name="android:dividerPadding">8dp</item>
        <item name="android:showDividers">middle</item>
        <item name="android:paddingLeft">10dp</item>
        <item name="android:paddingRight">10dp</item>
        <item name="android:fadingEdge">horizontal</item>
        <item name="android:fadingEdgeLength">8dp</item>
    </style>

    <style name="CustomTabPageIndicator.Text" parent="android:TextAppearance.Medium">
        <item name="android:typeface">monospace</item>
        <item name="android:textColor">@drawable/selector_tabtext</item>
    </style>

当然你也可以使用默认的样式。
新建AS项目,import library module,并在自己的工程中添加依赖:compile project(':library')
工程搭建好后如图:
这里写图片描述

下面便开始写代码了。
首先activity_main.xml。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.viewpagerindicator.TabPageIndicator
            android:id="@+id/indicator"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#dcdcdc" />

        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="16dp">

            <RadioButton
                android:id="@+id/show"
                style="@style/TabTextStyle"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="首页" />

            <RadioButton
                android:id="@+id/handpick"
                style="@style/TabTextStyle"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="功能" />

            <RadioButton
                android:id="@+id/me"
                style="@style/TabTextStyle"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="我的" />

        </RadioGroup>

    </LinearLayout>

</android.support.v4.widget.SwipeRefreshLayout>

SwipeRefreshLayout用于下拉刷新,TabPageIndicator便是选项卡Indicator,与ViewPager结合实现滑动。ViewGroup是我打算用来控制底部Tab切换的。
MainActivity代码如下:

public class MainActivity extends FragmentActivity implements SwipeRefreshLayout.OnRefreshListener {

    private SwipeRefreshLayout swipeLayout;
    private static final String[] TITLE = new String[]{"Recent", "Artists", "Albums", "Songs", "Playlists", "Genres"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
        // 顶部刷新的样式
        swipeLayout.setColorSchemeResources(android.R.color.holo_red_light,
                android.R.color.holo_green_light,
                android.R.color.holo_blue_bright,
                android.R.color.holo_orange_light);
        swipeLayout.setOnRefreshListener(this);
        // ViewPager结合Indicator
        FragmentPagerAdapter adapter = new TabPageIndicatorAdapter(getSupportFragmentManager());
        ViewPager pager = (ViewPager) findViewById(R.id.pager);
        pager.setAdapter(adapter);
        TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator);
        indicator.setViewPager(pager);
        indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {
                Toast.makeText(getApplicationContext(), TITLE[arg0], Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {

            }
        });

    }

    /**
     * TabPageIndicatorAdapter类
     */
    class TabPageIndicatorAdapter extends FragmentPagerAdapter {
        public TabPageIndicatorAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // 示例,新建一样的Fragment,传入String进行显示
            Fragment fragment = new ItemFragment();
            Bundle args = new Bundle();
            args.putString("arg", TITLE[position]);
            fragment.setArguments(args);
            return fragment;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return TITLE[position % TITLE.length];
        }

        @Override
        public int getCount() {
            return TITLE.length;
        }
    }

    /**
     * SwipeRefreshLayout刷新接口
     */
    @Override
    public void onRefresh() {
        // 模拟网络加载,1秒刷新
        Timer task = new Timer();
        task.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        swipeLayout.setRefreshing(false);
                    }
                });
            }
        }, 1000);
    }
}

下面看到ItemFragment。

public class ItemFragment extends Fragment {

    private TextView text;
    private RecyclerView recycler;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    private static final String[] data = new String[]{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View contextView = inflater.inflate(R.layout.fragment_item, container, false);
        this.recycler = (RecyclerView) contextView.findViewById(R.id.recycler);
        this.text = (TextView) contextView.findViewById(R.id.text);
        Bundle mBundle = getArguments();
        String title = mBundle.getString("arg");
        text.setText(title);
        recycler.setHasFixedSize(true);
        // 使用线性布局
        mLayoutManager = new LinearLayoutManager(getActivity());
        recycler.setLayoutManager(mLayoutManager);
        // 创建Adapter
        mAdapter = new MyAdapter(getActivity(), data);
        recycler.setAdapter(mAdapter);
        return contextView;
    }

}

fragment_item.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:orientation="vertical">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="18sp" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="4dp"
        android:paddingRight="4dp"
        android:scrollbars="vertical" />

</LinearLayout>

再来看到MyAdapter。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private String[] data;
    private Context mContext;

    public MyAdapter(Context context, String[] data) {
        mContext = context;
        this.data = data;
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View item = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item_card, parent, false);
        return new ViewHolder(item);
    }

    @Override
    public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
        holder.getTextView().setText(data[position]);
    }

    @Override
    public int getItemCount() {
        if (data != null) {
            return data.length;
        }
        return 0;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private TextView mTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView.findViewById(R.id.my_text1);
        }

        public TextView getTextView() {
            return mTextView;
        }
    }
}

使用RecyclerView,Adapter需要继承RecyclerView.Adapter。
下面看下recycler_item_card.xml。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/my_text1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:padding="8dp"
            android:textSize="18sp" />
    </LinearLayout>


</android.support.v7.widget.CardView>

就是很简单的CardView布局了。
下面来看下运行的效果:
这里写图片描述

可以看到效果还是不错的。

源码下载


总结:

  • 使用ViewPagerIndicator与ViewPager结合实现顶部Tab切换滑动效果。
  • 使用Google官方刷新SwipeRefreshLayout。
  • 使用RecycerView替代ListView、GridView。
  • Item布局使用CardView,实现圆角、阴影的布局,看起来效果更加。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值