SectionedRecyclerViewAdapter

在gradle.properties中添加:android.enableAapt2 = false


添加网络权限:<uses-permission android:name="android.permission.INTERNET"/>


添加依赖:

    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.truizlop.sectionedrecyclerview:library:1.2.0'
    implementation 'com.android.support:recyclerview-v7:26.1.0'


    compile 'com.squareup.retrofit2:converter-gson:2.3.0'


    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    compile "io.reactivex.rxjava2:rxjava:2.1.5"
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'


    compile 'com.github.bumptech.glide:glide:3.8.0'




布局文件.xml

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.day09_zuoye.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

item_movie.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="16dp"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/pic_iv"
        android:src="@mipmap/ic_launcher"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:text="asdasdasdasdasd"
        android:id="@+id/title_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

item_movie_footer.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp">

    <TextView
        android:id="@+id/footer_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="查看更多"
        android:textColor="#666666" />

</RelativeLayout>

item_movie_header.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp">

    <TextView
        android:id="@+id/header_tv"
        android:textSize="28sp"
        android:textColor="#666666"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>



MainActivity.java

package com.example.day09_zuoye;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.example.day09_zuoye.adapter.MovieAdapter;
import com.example.day09_zuoye.bean.MovieBean;
import com.example.day09_zuoye.httpservice.MovieHttpService;

import java.util.List;

import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {

    protected RecyclerView mRecyclerView;
    private Retrofit mRetrofit;

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

        loadData();
    }

    private void loadData() {
        mRetrofit = new Retrofit.Builder()
                .baseUrl("http://api.shigeten.net/")
                .addConverterFactory( GsonConverterFactory.create())
                .addCallAdapterFactory( RxJava2CallAdapterFactory.create())
                .build();

        Observable<MovieBean> observable = mRetrofit.create(MovieHttpService.class)
                .getObservable();

        observable.subscribeOn( Schedulers.io())
                .map(new Function<MovieBean, List<MovieBean.ResultBean>>() {
                    @Override
                    public List<MovieBean.ResultBean> apply(MovieBean movieBean) throws Exception {
                        return movieBean.getResult();
                    }
                })
                .observeOn( AndroidSchedulers.mainThread())
                .subscribe(new Consumer<List<MovieBean.ResultBean>>() {
                    @Override
                    public void accept(List<MovieBean.ResultBean> resultBeans) throws Exception {
                        MovieAdapter adapter = new MovieAdapter(MainActivity.this, resultBeans);
                        mRecyclerView.setAdapter(adapter);
                    }
                });
    }

    private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        // 设置列表布局管理者
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
    }
}

adapter文件夹下MovieAdapter.java

package com.example.day09_zuoye.adapter;


import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.day09_zuoye.R;
import com.example.day09_zuoye.bean.MovieBean;
import com.example.day09_zuoye.viewholder.MovieFooterViewHolder;
import com.example.day09_zuoye.viewholder.MovieHeaderViewHolder;
import com.example.day09_zuoye.viewholder.MovieViewHolder;
import com.truizlop.sectionedrecyclerview.SectionedRecyclerViewAdapter;

import java.util.ArrayList;
import java.util.List;

public class MovieAdapter extends SectionedRecyclerViewAdapter<MovieHeaderViewHolder, MovieViewHolder, MovieFooterViewHolder> {

    private Context mContext;
    // Activity传进来的原始数据集合
    private List<MovieBean.ResultBean> mDatas;

    // 每段中item数据的集合
    private List<MovieBean.ResultBean> mResultList;
    // 段落集合
    private List<List<MovieBean.ResultBean>> mSectionList;

    // 每段中item的数量
    private int mItemCountForSection = 2;

    // 标题的集合
    private List<String> mTitleList;

    // 段数
    private int mSectionCount;

    public MovieAdapter(Context context, List<MovieBean.ResultBean> datas) {
        mContext = context;
        mDatas = datas;

        initTitle();
        changeData(mDatas);
    }

    // 对原始数据变化:第xxx段中的第xxx个数据
    private void changeData(List<MovieBean.ResultBean> datas) {
        mSectionList = new ArrayList<>();

        for (int i = 0; i < datas.size(); i++) {
            if (i % 2 == 0) {
                mResultList = new ArrayList<>();
                mResultList.add(datas.get(i));
                // item数量的奇偶判断
                if (datas.size() / 2 == 0) {
                    mResultList.add(datas.get(i + 1));
                } else {
                    if (i < datas.size() - 1) {
                        mResultList.add(datas.get(i + 1));
                    }
                }
                mSectionList.add(mResultList);
            }
        }
    }


    // 初始化全部标题
    private void initTitle() {
        mSectionCount = mDatas.size() / mItemCountForSection + mDatas.size() % mItemCountForSection;

        mTitleList = new ArrayList<>();
        // 标题数量跟随段落数量而确定
        for (int i = 0; i < mSectionCount; i++) {
            mTitleList.add("标题:" + i);
        }
    }

    // 获取大item(段落)的数量
    @Override
    protected int getSectionCount() {
        return mDatas.size() / mItemCountForSection + mDatas.size() % mItemCountForSection;
    }

    // 每个段落中item数据的数量
    @Override
    protected int getItemCountForSection(int section) {
        int count;
        if (section == mSectionCount - 1) {// 最后一段
            count = (mDatas.size() / 2 == 0) ? 2 : 1;
        } else {
            count = 2;
        }
        return count;
    }


    // 控制段落中是否展示尾视图
    @Override
    protected boolean hasFooterInSection(int section) {
        return true;
    }

    // 创建头视图ViewHolder
    @Override
    protected MovieHeaderViewHolder onCreateSectionHeaderViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext)
                .inflate( R.layout.item_movie_header, parent, false);
        return new MovieHeaderViewHolder(itemView);
    }

    // 创建尾视图ViewHolder
    @Override
    protected MovieFooterViewHolder onCreateSectionFooterViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext)
                .inflate(R.layout.item_movie_footer, parent, false);
        return new MovieFooterViewHolder(itemView);
    }

    // 创建项数据item视图ViewHolder
    @Override
    protected MovieViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext)
                .inflate(R.layout.item_movie, parent, false);
        return new MovieViewHolder(itemView);
    }

    // 头视图数据的绑定(UI控件展示数据)
    @Override
    protected void onBindSectionHeaderViewHolder(MovieHeaderViewHolder holder, int section) {
        String title = mTitleList.get(section);
        holder.bind(title);
    }

    // 尾视图数据的绑定(UI控件展示数据)
    @Override
    protected void onBindSectionFooterViewHolder(MovieFooterViewHolder holder, int section) {

    }

    // 详细数据item视图数据的绑定(UI控件展示数据)
    @Override
    protected void onBindItemViewHolder(MovieViewHolder holder, int section, int position) {
        // 获取第section段中的第position个数据
        Log.d("1510", "section: " + section + ", position : " + position);
        MovieBean.ResultBean result = mSectionList.get(section).get(position);

        holder.bind(result);

    }
}

bean文件夹下MovieBean.java

package com.example.day09_zuoye.bean;

import java.util.List;

public class MovieBean {
    /**
     * result : [{"id":100483,"type":1,"publishtime":636505344000000000,"title":"《离开的女人》计划好退场却全神贯注看完四小时","summary":"这是一部接近伟大的电影,虽然结尾有些拖沓。另外电影可以剪辑到3个小时,但这部电影无论如何不能剪到3个小时以下。\r\n\r\n女主人公被富人陷害,在监狱里关了20年,被宣布无罪释放之后,她回家把地卖了,卖地的钱用来施行复仇,这本身就说明她的社会经济地位并不算太低。在反复踩点观察下手时机的过程中,她接触到菲律宾社会最底层的小百姓,生活对他们来说每天都是地狱。女主人公因此放弃复仇计划,回城市去找她失散的儿子。\r\n\r\n电影中Hollanda 为了报答女主人公善良,趁女主人公喝醉之际,偷了她的枪去杀她的仇人。电影里Hollanda 刺杀成功。但我觉得应该拍成刺杀不成功,反而被富人的保镖打死。这样的结局更自然,也更显悲剧。\r\n\r\n导演Lav Diaz 对菲律宾社会的底层小人物充满了同情,他早年做新闻记者的经历对他拍摄电影有很大的帮助。","image":"images/342742C2CD5CC6FD60D142038C88D548.png"},{"id":100482,"type":1,"publishtime":636504480000000000,"title":"《嘉年华》必须克制的态度","summary":"电影聚焦着赤裸裸的痛点,却又无处呐喊,无处宣泄,或许这就是现实。2017媲美《相爱相亲》的华语佳作,就像耿乐说的,这样的电影能公映已经很欣慰了\u2026\r\n\r\n少女性侵案,同情很容易,手撕罪犯也不难,但除此以外呢?片中两位母亲的做法,恐怕正好解释了悲剧不是随机并无意发生的。相比不可饶恕的恶,不自知其过的罪更是笼罩在中国社会的乌云,与当下时愈发强大的男权功守道不谋而合。精准的镜头,几乎没有废戏,视点交还予女孩的处理方法真心很棒。","image":"images/080C6F7487D19E0EB52EA7FFD5906F63.png"},{"id":100481,"type":1,"publishtime":636503616000000000,"title":"《一日情人》我以前也像你一样","summary":"1.恋爱中的人忘却了思考,舒服就好,幸福得如同傻子一样;\r\n\r\n2.男人如果要背叛你,不会提前告诉你的,而你能做的,就是跟他做同样的事;\r\n\r\n3.性格决定命运,同样决定着爱情的模样;\r\n\r\n4.导演镜头里的女演员,非常好看。","image":"images/EC1B95F11AF446539335EEFD1A713BB2.png"},{"id":100480,"type":1,"publishtime":636502752000000000,"title":"《伯德小姐 》成长里那些必然的抗争","summary":"这样简单温情的小品,在家人、爱情、和友谊之间周旋,却始终没有偏离成长这个棘手却永恒的问题。这部电影又好似一个珠宝盒,把最讨喜最会演戏的一帮年轻人囊括其中,让这部电影瞬间真切又充满活力。","image":"images/63ABEB90013921ACD7410E2F20F71B92.png"},{"id":100479,"type":1,"publishtime":636501888000000000,"title":"《自由之丘》句序自由,故事才自由","summary":"它可能是一部探讨时间的电影,男主人公手里总是拿着一本标题就是\u201c时间\u201d的书籍。故事从女教师在语言学校的前台收到日本男人的信件开始,男人告诉她,他已经来到她的城市,住在她周围,去她常去的咖啡馆,却寻她无果\u2026\u2026这是分写在一沓纸片上的自叙文,女教师不小心打翻了它们,每片都记录着男人的等待,和日常生活。当她从新拾起来阅读,男人要倾诉的这些日子的顺序自然被打乱了。","image":"images/AD8D78CFA74EDA7A15A12ABE92140325.png"},{"id":100478,"type":1,"publishtime":636501024000000000,"title":"《冰上轻驰》尊严与青春","summary":"本片根据一则真人真事改变而成,讲述奥运史上一段传奇故事。于1988年,四个来自牙买加的运动员,竟然凭着意志进军冬季奥运会,并在雪橇滑行比赛当中取得骄人成绩,同时赢得各国运动员的支持与鼓励。骤眼看来,将这样的史实板上银幕,无疑属励志片格局,但令观众想不到的,使全片拍摄手法轻松风趣,充满喜剧成分,而演员本身亦能发挥搞笑效果,令影片生色不少。","image":"images/8608B9B9A24C99F3DD2909782D08BCD7.png"},{"id":100007,"type":1,"publishtime":636500160000000000,"title":"《勇敢传说》合格的童话故事,一流的画面效果,不到位的女性主义","summary":"这仍旧是一部水准很高的动画电影。抛开技术层面不谈,单是这次在风格上的转型尝试就足见勇气和诚意。","image":"images/5FCE711751120087FDAB5770220AB890.jpg"},{"id":100477,"type":1,"publishtime":636499296000000000,"title":"《脸庞,村庄》汹涌无尽的悉达多之颜","summary":"他不再看见自己朋友悉达多的脸,却代之以其他的脸庞,许许多多、长长一大串的脸\u2026\u2026这人的笑容让他回忆起所有的一切,回忆起自己一生中当年曾经爱过的一切,回忆起自己一生中当年曾经认为有价值和神圣的一切。","image":"images/7780E9749657E47271B47B91CE426639.png"},{"id":100476,"type":1,"publishtime":636498432000000000,"title":"《一呼一吸》那些所谓的英雄主义,无非是想活得像正常人一样罢了","summary":"爱如空气,一呼一吸。\r\n\r\n你听懂了那句\u201cI don't want to just survive. I want to truly live.\u201d但是又有多少人能明白,对于一个瘫痪的人,到底需要放弃多少次自杀的念头才能有可能拥有所谓的truly live?","image":"images/D3C35057A1646E1A30035CAE250C8ECF.png"}]
     * status : 0
     * errMsg : null
     */

    private int status;
    private Object errMsg;
    private List<ResultBean> result;

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public Object getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(Object errMsg) {
        this.errMsg = errMsg;
    }

    public List<ResultBean> getResult() {
        return result;
    }

    public void setResult(List<ResultBean> result) {
        this.result = result;
    }

    public static class ResultBean {
        /**
         * id : 100483
         * type : 1
         * publishtime : 636505344000000000
         * title : 《离开的女人》计划好退场却全神贯注看完四小时
         * summary : 这是一部接近伟大的电影,虽然结尾有些拖沓。另外电影可以剪辑到3个小时,但这部电影无论如何不能剪到3个小时以下。

         女主人公被富人陷害,在监狱里关了20年,被宣布无罪释放之后,她回家把地卖了,卖地的钱用来施行复仇,这本身就说明她的社会经济地位并不算太低。在反复踩点观察下手时机的过程中,她接触到菲律宾社会最底层的小百姓,生活对他们来说每天都是地狱。女主人公因此放弃复仇计划,回城市去找她失散的儿子。

         电影中Hollanda 为了报答女主人公善良,趁女主人公喝醉之际,偷了她的枪去杀她的仇人。电影里Hollanda 刺杀成功。但我觉得应该拍成刺杀不成功,反而被富人的保镖打死。这样的结局更自然,也更显悲剧。

         导演Lav Diaz 对菲律宾社会的底层小人物充满了同情,他早年做新闻记者的经历对他拍摄电影有很大的帮助。
         * image : images/342742C2CD5CC6FD60D142038C88D548.png
         */

        private int id;
        private int type;
        private long publishtime;
        private String title;
        private String summary;
        private String image;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public long getPublishtime() {
            return publishtime;
        }

        public void setPublishtime(long publishtime) {
            this.publishtime = publishtime;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getSummary() {
            return summary;
        }

        public void setSummary(String summary) {
            this.summary = summary;
        }

        public String getImage() {
            return image;
        }

        public void setImage(String image) {
            this.image = image;
        }
    }
}

httpservice文件夹下MovieHttpService.java

package com.example.day09_zuoye.httpservice;


import com.example.day09_zuoye.bean.MovieBean;

import io.reactivex.Observable;
import retrofit2.http.GET;

public interface MovieHttpService {

    @GET("api/Critic/GetCriticList")
    Observable<MovieBean> getObservable();

}

viewholder文件夹下:

MovieFooterViewHolder.java

package com.example.day09_zuoye.viewholder;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

import com.example.day09_zuoye.R;


/**
 * Created by estyle on 2018/1/4.
 */

public class MovieFooterViewHolder extends RecyclerView.ViewHolder {

    TextView mFooterTextView;

    public MovieFooterViewHolder(View itemView) {
        super(itemView);

        mFooterTextView = itemView.findViewById( R.id.footer_tv);
    }
}

MovieHeaderViewHolder.java

package com.example.day09_zuoye.viewholder;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

import com.example.day09_zuoye.R;


/**
 * Created by estyle on 2018/1/4.
 */

public class MovieHeaderViewHolder extends RecyclerView.ViewHolder {

    TextView mHeaderTextView;

    public MovieHeaderViewHolder(View itemView) {
        super(itemView);

        mHeaderTextView = itemView.findViewById( R.id.header_tv);
    }

    public void bind(String title) {
        mHeaderTextView.setText(title);
    }

}

MovieViewHolder.java

package com.example.day09_zuoye.viewholder;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.day09_zuoye.R;
import com.example.day09_zuoye.bean.MovieBean;


public class MovieViewHolder extends RecyclerView.ViewHolder {

    TextView mTitleTextView;
    ImageView mPicImageView;

    public MovieViewHolder(View itemView) {
        super(itemView);

        mTitleTextView = itemView.findViewById( R.id.title_tv);
        mPicImageView = itemView.findViewById(R.id.pic_iv);
    }

    public void bind(MovieBean.ResultBean result) {
        mTitleTextView.setText(result.getTitle());

        Glide.with(mPicImageView.getContext())
                .load("http://api.shigeten.net/" + result.getImage())
                .into(mPicImageView);
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值