最近在进行毕业设计,想要做一个线性流的资讯页面,在网上找了一下,好像对这块的描写都不太清楚。
在这个demo中我需要实现下拉刷新,上拉加载等。
首先导入github大神的开源库:
GitHub地址:https://github.com/jdsjlzx/LRecyclerView/
Step 1. 在你的根build.gradle文件中增加JitPack仓库依赖。
allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
}
Step 2. 在你的module的build.gradle文件中增加LRecyclerView依赖。
implementation 'com.github.jdsjlzx:LRecyclerView:1.5.4.3'
在这里我先把布局给安排好:
这个xml页面用来放置一整个LRecyclerView,我打算整个页面都用于资讯页,因此高度用了wrap_content,需要自定义其他功能的可以自己加。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical">
<com.github.jdsjlzx.recyclerview.LRecyclerView
android:id="@+id/lrv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</com.github.jdsjlzx.recyclerview.LRecyclerView>
</LinearLayout>
接着再新建一个xml文件,在这个页面上,我们要放置你的单个ListView样式
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@color/color_hint"
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:padding="5dp"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/iv_icon"
android:layout_width="160dp"
android:layout_height="120dp"
android:gravity="left"
android:scaleType="fitXY">
</ImageView>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:text="官宣!首尔马拉松宣布赛事取消 全额退还报名费"
android:textAllCaps="false"
android:textColor="@color/black"
android:textSize="24sp">
</TextView>
</LinearLayout>
</RelativeLayout>
在这个xml内,你可以自己调节样式的摆放,接下来每个生成都会这个样子。
接下来我们需要添加一个适配器adapter,我们的数据添加与修改都要通过这个适配器。
public class DataAdapter extends LRecyclerView.Adapter<DataAdapter.RecyclerViewHodler> {
private final Context context;
private ArrayList<String> datas;
private Bitmap[] bitmaps;
private ArrayList<String> urls;
public DataAdapter(Context context) {
this.context = context;
}
/**
* 这里找到你的listview
* @param parent
* @param viewType
* @return
*/
@NonNull
@Override
public RecyclerViewHodler onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = View.inflate(context, R.layout.item_lrecyclerview,null);
return new RecyclerViewHodler(itemView);
}
/**
* 这里实现数据的绑定
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(@NonNull RecyclerViewHodler holder, int position) {
System.out.println(position);
System.out.println(datas.get(position));
// System.out.println(bitmaps[position]);
String data = datas.get(position);
// Bitmap bmp = bitmaps[position];
holder.tv_title.setText(data);
// holder.iv_icon.setImageBitmap(bmp);
Glide.with(context).load(urls.get(position)).into(holder.iv_icon);
}
/**
* 这里返回Item的数量
* @return
*/
@Override
public int getItemCount() {
return datas.size();
}
/**
* 这里引出数据的接口
* @param datas
* @param urls
*/
public void setData(ArrayList<String> datas,ArrayList<String> urls) {
this.datas = datas;
// this.bitmaps = bitmaps;
this.urls = urls;
}
/**
* 这里实现下拉刷新和上拉加载数据的添加
* @param listDatas
* @param listUrls
*/
public void addAll(ArrayList<String> listDatas , ArrayList<String> listUrls) {
int lastIndex = this.datas.size();
if (this.datas.addAll(listDatas) && this.urls.addAll(listUrls)) {
notifyItemRangeInserted(lastIndex, listDatas.size());
}
}
/**
* 下拉刷新时对原来的数据进行清除
*/
public void clear() {
datas.clear();
urls.clear();
notifyDataSetChanged();
}
/**
* find view
*/
class RecyclerViewHodler extends LRecyclerView.ViewHolder{
private ImageView iv_icon;
private TextView tv_title;
public RecyclerViewHodler(@NonNull View itemView) {
super(itemView);
iv_icon = itemView.findViewById(R.id.iv_icon);
tv_title = itemView.findViewById(R.id.tv_title);
}
}
}
这部分的注释也写清楚了,数据在fragment或者activity获取到后,再传入adapter进行数据的绑定。
接下来就是最主要的数据逻辑部分:
public class NotificationsFragment extends Fragment {
private static final String TAG = "NotificationsFragment";
private NotificationsViewModel notificationsViewModel;
private LRecyclerView mRecyclerView;
private ArrayList<String> datas ;
private LRecyclerViewAdapter mLRecyclerViewAdapter;
//数据的适配器
private DataAdapter mDataAdapter;
//响应数据
private String resposeBody;
//图片的url
private ArrayList<String> urls;
//跳转链接
private ArrayList<String> imformationUrls;
/**
* 已经获取到多少条数据了
*/
private static int mCurrentCounter = 0;
private int page = 1;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
notificationsViewModel = ViewModelProviders.of(this).get(NotificationsViewModel.class);
View view = inflater.inflate(R.layout.fragment_notifications, container, false);
getDatas(page);
dataGson();
initRecyclerView(view);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
private void notifyDataSetChanged() {
mLRecyclerViewAdapter.notifyDataSetChanged();
}
private void addItems(ArrayList<String> list1 ,ArrayList<String> list2) {
mDataAdapter.addAll(list1, list2);
mCurrentCounter += list1.size();
}
private void getDatas(int page) {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS) // 设置连接超时时间
.readTimeout(20, TimeUnit.SECONDS) // 设置读取超时时间
.build();
String url = "**";//这里填写你的数据接口
System.out.println(url);
Request request = new Request.Builder()
.url(url)
.build();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = client.newCall(request).execute();
resposeBody = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
try {
t.join();//这个地方我发现由于请求量可能比较大,子线程的网络请求太慢了会导致数据请求异常,因此加入了thread.join方法,保证网络请求的完整。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void dataGson() {
Gson gson = new Gson();
imformationBean imformationBean1 = gson.fromJson(resposeBody, imformationBean.class);
List list1 = imformationBean1.getData();
System.out.println(list1.size());
datas = new ArrayList<>();
urls = new ArrayList<>();
imformationUrls = new ArrayList<>();
for (int i = 0; i < list1.size(); i++)
{
imformationBean.DataBean dataBean = (imformationBean.DataBean) list1.get(i);
List<String> images = dataBean.getImages();
datas.add(dataBean.getMobileTitle());
urls.add("http://" + images.get(0).substring(2));
imformationUrls.add(getString(R.string.imformation_url) + dataBean.getUrl());
}
}
private void initRecyclerView(View view) {
mRecyclerView = view.findViewById(R.id.lrv);
mDataAdapter = new DataAdapter(getActivity());
mDataAdapter.setData(datas,urls);
mLRecyclerViewAdapter = new LRecyclerViewAdapter(mDataAdapter);
mRecyclerView.setAdapter(mLRecyclerViewAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL,false));
mRecyclerView.setRefreshProgressStyle(ProgressStyle.LineSpinFadeLoader);
mRecyclerView.setLoadingMoreProgressStyle(ProgressStyle.BallSpinFadeLoader);
//设置头部加载颜色
mRecyclerView.setHeaderViewColor(R.color.colorAccent, R.color.black ,android.R.color.white);
//设置底部加载颜色
mRecyclerView.setFooterViewColor(R.color.colorAccent, R.color.black ,android.R.color.white);
//设置底部加载文字提示
mRecyclerView.setFooterViewHint("拼命加载中","已经全部为你呈现了","网络不给力啊,点击再试一次吧");
mLRecyclerViewAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
//此处进行监听事件的业务处理
Intent intent = new Intent();
intent.setData(Uri.parse(imformationUrls.get(position)));//Url 就是你要打开的网址
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent); //启动浏览器
Toast.makeText(getActivity(),"我是item" + position ,Toast.LENGTH_SHORT).show();
}
});
mRecyclerView.setOnNetWorkErrorListener(new OnNetWorkErrorListener() {
@Override
public void reload() {
Toast.makeText(getActivity(),"网络异常" ,Toast.LENGTH_SHORT).show();
}
});
mRecyclerView.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
mCurrentCounter = 0;
mDataAdapter.clear();
page = 1;
getDatas(page);
dataGson();
addItems(datas,urls);
mRecyclerView.refreshComplete(1);
}
});
mRecyclerView.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
getDatas(page++);
dataGson();
addItems(datas,urls);
mRecyclerView.refreshComplete(1);
}
});
}
}
代码风格很菜…仅作参考。希望可以帮到大家