團隊app項目衝刺三

今天完成的任務:實現筆記展示界面的上拉刷新和下拉加載

遇到的困難:

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

 

下拉提示信息界面佈局

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章