美文网首页Android知识AndroidAndroid开发技术中心
一起撸一波干货集中营练练手Android(三)布局+实现篇

一起撸一波干货集中营练练手Android(三)布局+实现篇

作者: Mapleslong | 来源:发表于2016-08-19 16:20 被阅读702次

    MPGankIO 布局篇

    整个App到了这里就开始准备开始实现逻辑啦,有没有点小期待
    后续如果有需要可以爬一波包包通缉令的数据O(∩_∩)O~~

    我们的布局采用5.0之后的新布局控件

    1.CardView

    CardView 对这个控件还不太了解的可以戳这里

    CardView特别的属性如下:
    
    android:cardCornerRadius:在布局中设置card圆角的大小
    CardView.setRadius:在代码中设置card圆角的大小
    android:cardBackgroundColor:在布局中设置card背景的颜色
    android:elevation:设置阴影的大小
    card_view:cardElevation 阴影的大小
    card_view:cardMaxElevation 阴影最大高度
    card_view:cardCornerRadius 卡片的圆角大小
    card_view:contentPadding 卡片内容于边距的间隔 
    card_view:contentPaddingBottom 
    card_view:contentPaddingTop 
    card_view:contentPaddingLeft 
    card_view:contentPaddingRight 
    card_view:contentPaddingStart 
    card_view:contentPaddingEnd
    card_view:cardUseCompatPadding 设置内边距,V21+的版本和之前的版本仍旧具有一样的计算方式
    **card_view:cardPreventConrerOverlap 
    在V20和之前的版本中添加内边距,这个属性为了防止内容和边角的重叠**
    
    
    • 我们要使用这个CardView来做卡片式的列表
    <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="wrap_content"
                                        android:layout_margin="5dp"
                                        android:foreground="?android:attr/selectableItemBackground"
                                        android:orientation="vertical"
                                        app:contentPadding="5dp">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@id/tv_title"
                style="@style/txt_normal_style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:ellipsize="end"
                android:gravity="start"
                android:maxLines="3"
                android:text="标题"
                android:textSize="16sp"
                />
    
    
            <TextView
                android:id="@id/tv_name"
                style="@style/txt_normal_style"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_below="@id/tv_title"
                android:layout_marginTop="10dp"
                android:gravity="bottom"
                android:text="作者"
                android:textColor="@color/colorPrimary"/>
    
            <TextView
                android:id="@id/tv_publishtime"
                style="@style/txt_normal_style"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_alignParentRight="true"
                android:layout_below="@id/tv_title"
                android:layout_marginTop="10dp"
                android:gravity="bottom"
                android:text="发表时间"/>
    
        </RelativeLayout>
    
    </android.support.v7.widget.CardView>
    
    

    CardView 大部分适用于 listView 或者recyclerView的item中。

    2.RecyclerView

    RecyclerView 可以戳这里了解一下

    RecyclerView与ListView原理是类似的:都是仅仅维护少量的View并且可以展示大量的数据集。RecyclerView用以下两种方式简化了数据的展示和处理:

    • 使用LayoutManager来确定每一个item的排列方式。
    • 为增加和删除项目提供默认的动画效果。

    你也可以定义你自己的LayoutManager和添加删除动画,SDK中默认包含了三种布局

     1. 横向布局(LinearLayoutManager)  
     2. Grid布局(GridLayoutManager) 
     3.  瀑布流布局(StaggeredGridLayoutManager)
    
    • Adapter:使用RecyclerView之前,你需要一个继承自RecyclerView.Adapter的适配器,作用是将数据与每一个item的界面进行绑定。
    • LayoutManager:用来确定每一个item如何进行排列摆放,何时展示和隐藏。回收或重用一个View的时候,
      LayoutManager会向适配器请求新的数据来替换旧的数据,这种机制避免了创建过多的View和频繁的调用findViewById方法(与ListView原理类似)。

    总而言之就相当于ListView封装后再抽象,使item更加灵活

     项目中我使用的是XRecyclerView,是封装了上拉刷新和下拉加载的一个库,非常好用还有挺多的加载动画可以切换,使用的方法也很简单,哈哈,偷懒!! 不都是说为了不要重复造轮子嘛~你懂的
    
    

    3.Fragment

    这个应该不用多讲了相信大家都会的

    4.代码附上

    MainFragment.java 这个就是为了在主页将一些数据初始化为了给TypeFragment拿到类型数据

    • 为什么使用FragmentStateAdapter而不用FragmentPagerAdapter是因为viewpager页数比较多
      FragmentStateAdatper的机制是空置的时候将其销毁释放内存,而FragmentPagerAdapter是将其dettach
      因此选用FragmentSteteAdapter

    GankViewPagerAdapter.java

    public class GankViewPagerAdapter extends FragmentStatePagerAdapter {
       
        private List<Fragment> mFragments;
        private List<String> mTitles;
    
        public GankViewPagerAdapter(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
            super(fm);
            this.mFragments = fragments;
            this.mTitles = titles;
        }
    
        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }
    
        @Override
        public int getCount() {
            return mFragments.size();
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return mTitles.get(position);
        }
    }
    
    

    大家如果之前理解过MVP架构应该就会发现我调用的方式啦!

    TypeFragment.java 核心模块

    
    public class TypeFragment extends BaseMvpFragment<TypeFragmentView, TypePresenter> implements
            TypeFragmentView {
        private static final String ARG_PARAM1 = "type";
        @BindView(R.id.rv_list)
        XRecyclerView rvList;
        private String mCategory;
        private View rootView;
        private GankTypeCardAdapter mGankTypeCardAdapter;
        private List<GankDataEntity> mDatas;
        private int curPage = 1;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (getArguments() != null) {
                mCategory = getArguments().getString(ARG_PARAM1);
            }
            initVariables();
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            rootView = inflater.inflate(R.layout.fragment_type, container, false);
            ButterKnife.bind(this, rootView);
            resetDatas();
            initViews();
            return rootView;
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putString(ARG_PARAM1, mCategory);
        }
    
        @Override
        public void onViewStateRestored(Bundle savedInstanceState) {
            super.onViewStateRestored(savedInstanceState);
            if (savedInstanceState != null) {
                mCategory = ConvertUtil.toString(savedInstanceState.getString(ARG_PARAM1), "");//避免为NULL
            }
        }
    
        @Override
        public void initVariables() {
            mDatas = new ArrayList<>();
        }
    
        @Override
        public void initViews() {
            initRecyclerView();
            presenter.getTypeGankList();
        }
    
        private void initRecyclerView() {
            rvList.setPullRefreshEnabled(true);
            rvList.setLoadingMoreEnabled(true);
            rvList.setLoadingListener(new XRecyclerView.LoadingListener() {
                @Override
                public void onRefresh() {
                    resetDatas();
                    presenter.getTypeGankList();
                }
    
                @Override
                public void onLoadMore() {
                    presenter.getTypeGankList();
                }
            });
        }
    
        @Override
        protected TypePresenter initPresenter() {
            return new TypePresenter();
        }
    
        public static TypeFragment newInstance(String type) {
            TypeFragment fragment = new TypeFragment();
            Bundle args = new Bundle();
            args.putString(ARG_PARAM1, type);
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public String getCategory() {
            return mCategory;
        }
    
        @Override
        public int getCurPage() {
            return curPage;
        }
    
        @Override
        public void addOnePage() {
            curPage++;
        }
    
        @Override
        public void makeUpDatas(List<GankDataEntity> datas) {
            mDatas.addAll(datas);
        }
    
        @Override
        public void notifyAdapter() {
            if (mGankTypeCardAdapter == null) {
                mGankTypeCardAdapter = new GankTypeCardAdapter(mActivity, mDatas);
                rvList.setLayoutManager(new LinearLayoutManager(mActivity));
                rvList.setAdapter(mGankTypeCardAdapter);
            }
            // TODO: 16/8/19 //此处可以优化成动画效果以及item逐个优化不需要整个重新排列
            mGankTypeCardAdapter.notifyDataSetChanged();
            rvList.refreshComplete();
            rvList.loadMoreComplete();
        }
    
        @Override
        public void resetDatas() {
            curPage = 1;
            mDatas.clear();
            if (mGankTypeCardAdapter != null) {
                mGankTypeCardAdapter.notifyDataSetChanged();
            }
        }
    
        @Override
        public void onDestroyView() {
            mGankTypeCardAdapter = null;
            super.onDestroyView();
        }
    }
    
    

    最后就是P中调用V啦 就是传说中的解耦


    到此基本上的请求列表功能结束啦,下一篇最终章就是列表点击事件和链接的内容页面!

    有问题可以来我博客或者简书反馈,谢谢大家的停留在这里时间

    附上源码下载地址

    相关文章

      网友评论

        本文标题:一起撸一波干货集中营练练手Android(三)布局+实现篇

        本文链接:https://www.haomeiwen.com/subject/fepbsttx.html