冲刺三

今天完成的任务:实现笔记展示界面的上拉刷新和下拉加载

遇到的困难:

1、加载recyclerview时偶尔出现刷新不成功的情况  原因:recyclerview中数据缓存的问题

2、上拉加载和下拉刷新冲突的过程  原因:主要是list集合中数据没有刷新(list集合中remove()方法的原理不清楚,这里采用的是模拟数据,注:使用remove()方法删除应从末尾开始删除,如果从头开始删除会比较麻烦)

3、模拟数据过多时,主线程承担压力较大,可能会出现延迟加载,还要考虑访问远程数据库用户网络不佳的状况。

解决思路:

1、数据变更时提示adpater中数据发生改变即可。(方法:adapter.notifyDataSetChanged())

2、上拉加载一共有刷新和到底两个状态,首先将到底提示属性设置为隐藏,remove方法从后往前删除,或更新。

3、新建一个子线程,由子线程完成相关查询操作,主线程只负责结果的展示,这里避免数据过多可以采用一次只查询十条数据。

明日的任务:

连接远程数据库,进行简单的登录注册验证。

 

附上代码:

底部提示信息布局,下拉刷新谷歌提供了SwipeRefreshLayout组件,直接重写方法即可,上拉加载需要自己编写。

<?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="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">

    <ProgressBar
        android:id="@+id/pb_loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminateDrawable="@drawable/progressbar_refresh"
        >
    </ProgressBar>

    <TextView
        android:id="@+id/tv_loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="15dp"
        android:text="正在加载中..."
        android:textColor="#4D6ABC"
        android:textSize="16sp"
        >
    </TextView>

    <LinearLayout
        android:id="@+id/ll_end"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:gravity="center"
        android:orientation="horizontal"
       >

        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1"
            android:alpha="0.5"
            android:background="#4DB6AC"
            >
        </View>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="我是有底线的"
            android:textColor="#4DB9AC"
            android:textSize="16sp">
        </TextView>

        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1"
            android:alpha="0.5"
            android:background="#4DB6AC"
            >
        </View>

    </LinearLayout>



</LinearLayout>
refresh_footer.xml

上拉加载更多需要更改Adapter

package com.itheima.cloudnotes.adapter;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.itheima.cloudnotes.Activity.Detail;
import com.itheima.cloudnotes.R;
import com.itheima.cloudnotes.enity.Note;

import java.util.List;

public class NoteAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
    private List<Note> mNoteList;
    private Context mContext;

    //普通布局
    private final int TYPE_ITEM = 1;
    //脚布局
    private final int TYPE_FOOTER=2;
    //当前为加载状态,默认为加载完成
    private int loadState=2;
    //正在加载
    public  final int LOADING=1;
    //加载完成
    public final int LOADING_COMPLETE=2;
    //加载到底
    public final int LOADING_END=3;

    @Override
    public int getItemViewType(int position)
    {
       //最后一个item设置为FootView
        if(position+1==getItemCount()){
            return TYPE_FOOTER;
        }else {
            return TYPE_ITEM;
        }
    }

    @NonNull
    @Override
    //onCreateViewHolder负责承载每个子项的布局。它有两个参数,其中一个是 int viewType;
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
    {
        mContext=parent.getContext();
        //进行判断显示类型,来创造返回不同的View
        if (viewType==TYPE_ITEM)
        {
            View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item,parent,false);
            return new  RecyclerViewHolder(view);
        }
        else if(viewType==TYPE_FOOTER)
        {
            View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.refresh_footer,parent,false);
            return new FootViewHolder(view);
        }
        return null;
    }

    //onBindViewHolder负责将每个子项holder绑定数据,俩参数分别是RecyclerView.ViewHolder holder, int position;
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position)
    {
        if(holder instanceof  RecyclerViewHolder)
        {
            RecyclerViewHolder recyclerViewHolder = (RecyclerViewHolder) holder;
            final Note note=mNoteList.get(position);
            recyclerViewHolder.icon.setImageResource(note.getIcon());
            recyclerViewHolder.tv_writer_name.setText(note.getWriter_name());
            recyclerViewHolder.tv_course.setText(note.getCourse());
            recyclerViewHolder.collect.setImageResource(note.getCollect());
            recyclerViewHolder.tv_title.setText(note.getTitle());
            recyclerViewHolder.tv_date.setText(note.getDate());

            recyclerViewHolder.tv_title.setOnClickListener(new View.OnClickListener( ) {
                @Override
                public void onClick(View v) {
                    Intent intent=new Intent(mContext,Detail.class);
                    intent.putExtra("writer_name",note.getWriter_name());
                    mContext.startActivity(intent);
                }
            });

            recyclerViewHolder.collect.setOnClickListener(new View.OnClickListener( ) {
                @Override
                public void onClick(View v) {

                }
            });
        }
        else if(holder instanceof FootViewHolder)
        {
            FootViewHolder footViewHolder = (FootViewHolder) holder;
            switch (loadState)
            {
                case LOADING: // 正在加载
                    footViewHolder.pbLoading.setVisibility(View.VISIBLE);
                    footViewHolder.tvLoading.setVisibility(View.VISIBLE);
                    footViewHolder.llEnd.setVisibility(View.GONE);
                    break;

                case LOADING_COMPLETE: // 加载完成
                    footViewHolder.pbLoading.setVisibility(View.INVISIBLE);
                    footViewHolder.tvLoading.setVisibility(View.INVISIBLE);
                    footViewHolder.llEnd.setVisibility(View.GONE);
                    break;

                case LOADING_END: // 加载到底
                    footViewHolder.pbLoading.setVisibility(View.GONE);
                    footViewHolder.tvLoading.setVisibility(View.GONE);
                    footViewHolder.llEnd.setVisibility(View.VISIBLE);
                    break;

                default:
                    break;
            }
        }
    }

    @Override
    public int getItemCount() {
        return mNoteList.size()+1;
    }

    public NoteAdapter(List<Note> mNoteList) {
        this.mNoteList = mNoteList;
    }

    private class  RecyclerViewHolder extends RecyclerView.ViewHolder{
        View NoteView;
        ImageView icon;
        TextView tv_writer_name;
        TextView tv_course;
        ImageView collect;
        TextView tv_title;
        TextView tv_date;

        public  RecyclerViewHolder(@NonNull View itemView) {
            super(itemView);
            NoteView=itemView;
            icon=itemView.findViewById(R.id.icon);
            tv_writer_name=itemView.findViewById(R.id.writer_name);
            tv_course=itemView.findViewById(R.id.course);
            collect=itemView.findViewById(R.id.collect);
            tv_title=itemView.findViewById(R.id.title);
            tv_date=itemView.findViewById(R.id.date);
        }
    }

    private class FootViewHolder extends RecyclerView.ViewHolder
    {
        ProgressBar pbLoading;
        TextView tvLoading;
        LinearLayout llEnd;

        public FootViewHolder(@NonNull View itemView)
        {
            super(itemView);
            pbLoading = (ProgressBar) itemView.findViewById(R.id.pb_loading);
            tvLoading = (TextView) itemView.findViewById(R.id.tv_loading);
            llEnd = (LinearLayout) itemView.findViewById(R.id.ll_end);
        }

    }

    //设置上拉加载状态  @param loadState 0.正在加载 1.加载完成 2.加载到底
    public void  setLoadState(int loadState)
    {
        this.loadState = loadState;
        notifyDataSetChanged();
    }

}
NoteAdapter

滑动监听

package com.itheima.cloudnotes.listener;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener
{
    //用来标记是否正在向上滑动
    private boolean isSlidingUpward = false;

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState)
    {
        super.onScrollStateChanged(recyclerView, newState);
        LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
        // 当不滑动时
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            //获取最后一个完全显示的itemPosition
            int lastItemPosition = manager.findLastCompletelyVisibleItemPosition();
            int itemCount = manager.getItemCount();

            // 判断是否滑动到了最后一个item,并且是向上滑动
            if (lastItemPosition == (itemCount - 1) && isSlidingUpward) {
                //加载更多
                onLoadMore();
            }
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy)
    {
        super.onScrolled(recyclerView, dx, dy);
        // 大于0表示正在向上滑动,小于等于0表示停止或向下滑动
        isSlidingUpward = dy > 0;
    }

    /**
     * 加载更多回调
     */
    public abstract void onLoadMore();
}
View Code

主活动中上拉加载和下拉刷新

 public void upMore()
    {
        // 设置加载更多监听
        recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener() {
            @Override
            public void onLoadMore() {
                noteAdapter.setLoadState(noteAdapter.LOADING);

                if (noteList.size()!=20) {
                    // 模拟获取网络数据,延时1s
                    new Timer().schedule(new TimerTask() {
                        @Override
                        public void run() {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    initNotes();
                                    noteAdapter.setLoadState(noteAdapter.LOADING_COMPLETE);
                                }
                            });
                        }
                    }, 1000);
                } else {
                    // 显示加载到底的提示
                    noteAdapter.setLoadState(noteAdapter.LOADING_END);
                }
            }
        });
    }

 @SuppressLint("ResourceAsColor")
    public void downFresh()
    {
        srl=findViewById(R.id.swipe_refresh_layout);//获取SwipeRefreshLayout实例
        srl.setColorSchemeColors(R.color.colorPrimary);//设置刷新进度颜色
        srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener( ) {
            @Override
            public void onRefresh()
            {
                new Thread(new Runnable( )
                {
                    @Override
                    public void run()
                    {
                        try
                        {
                            Thread.sleep(100); //为了体现刷新效果,这里休眠了线程
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace( );
                        }
                        //切回主线程
                        runOnUiThread(new Runnable( ) {
                            @Override
                            public void run() {
                                initNotes1(); //重新刷新数据
                                noteAdapter.notifyDataSetChanged();//通知数据已发生变化
                                srl.setRefreshing(false);//当刷新结束时隐藏刷新条
                            }
                        });
                    }

                }).start();

            }
        });
    }
View Code

 

下拉提示信息界面布局

 

posted @ 2020-04-16 10:25  一粒盐  阅读(135)  评论(0编辑  收藏  举报