摘要:為用于顯示復雜視圖的新增。建議大家參考上拉更多具體使用不講了,今天我們順便講一下如何在加上拉更多的效果吧,下拉刷新我們使用的效果就行。因為我看市面上目前大部分的都是這樣做的,下拉刷新用的效果,自己在上添加上拉更多。
RecyclerView RecyclerView介紹去年很早之前,我就講解過RecyclerView的使用,今天我們就在講解CardView的時候,順便再把RecyclerView同時講解一下。RecyclerView、CardView為用于顯示復雜視圖的新增Widget。接下來看看如何使用吧。
RecyclerView作為替代ListView使用,它更先進,更靈活,RecyclerView標準化了ViewHolder,ListView中convertView是復用的,在RecyclerView中,是把ViewHolder作為緩存的單位了,然后convertView作為ViewHolder的成員變量保持在ViewHolder中,也就是說,假設手機屏幕可顯示10個條目,則會創建10個ViewHolder緩存起來,每次復用的是ViewHolder,所以他把getView這個方法變為了onCreateViewHolder。 ViewHolder更適合多種子布局的列表,尤其IM聊天對話框列表。
注意的是:RecyclerView不提供ListView中的setOnItemClickListener方法,我們可以在ViewHolder中添加類似的點擊事件。
RecyclerView注意事項,如何用雖然RecyclerView充分考慮了它的擴展性,更好用,更靈活,但是用起來也有些麻煩。所以要使用RecyclerView,要好好考慮以下幾點:
RecyclerView.Adapter:RecyclerView.Adapter包含了一種新型適配器,其實與以前我們使用的適配器基本類似,只是稍微有所不同,比如viewholder它幫我們封裝好了,不用像以前使用listview的適配器一樣自己去寫viewholder了。所以它的性能比以前應該好了不少。
LayoutManager:這個LayoutManager類決定視圖被放在畫面中哪個位置,但這只是它的眾多職責之一。它可以管理滾動和循環利用。LayoutManager是一個抽象類,好在系統提供了3個實現類:
1、LinearLayoutManager 現行管理器,支持橫向、縱向。
2、GridLayoutManager 網格布局管理器
3、 StaggeredGridLayoutManager 瀑布就式布局管理器
ItemAnimator:ItemAnimator簡單來說是會根據適配器上收到的相關通知去動畫的顯示組件的修改,添加和刪除等。它會自動添加和移除item的動畫。自帶的默認效果也不錯,已經非常好了。
如何用呢?這里我就不過多介紹了,因為關于RecyclerView的使用,去年我很早時間就寫過一篇文章。建議大家參考:
http://mp.weixin.qq.com/s?__biz=MjM5NDkxMTgyNw==&mid=208467006&idx=1&sn=c29971b395611008319222eaffad4f31#rd
RecyclerView具體使用不講了,今天我們順便講一下如何在RecyclerView加上拉更多的效果吧,下拉刷新我們使用SwipeRefreshLayout的效果就行。因為我看市面上目前大部分的app都是這樣做的,下拉刷新用SwipeRefreshLayout的效果,自己在RecyclerView上添加上拉更多。
很可惜的是,RecyclerView并沒有像ListView那樣提供給我們addFooterView()那樣的方法,那該如何實現呢?前面我們介紹RecyclerView時,說過RecyclerView適合多種嵌套的布局效果, ViewHolder更適合多種子布局的列表。所以我們看 RecyclerView的Adapter中的一個方法如下:
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
看到viewType了吧,就是在這里處理多種布局效果,上拉更多的布局和其他item其實沒有什么區別。所以處理方式大家都知道了吧。
第一步:添加布局狀態標識,并增加一項FooterView
在adapter中聲明布局狀態標識,是普通布局還是foot布局
private static final int TYPE_NORMAL_ITEM = 0; //普通Item private static final int TYPE_FOOTER_ITEM = 1; //底部FooterView
在getItemCount()中加1
@Override public int getItemCount() { //+1是加入底部的加載布局項 return list.size() + 1; }
第二步:重寫getItemViewType判斷不同布局
public int getItemViewType(int position) { // 如果position+1等于整個布局所有數總和就是底部布局 if (position + 1 == getItemCount()) { return TYPE_FOOTER_ITEM; } else { return TYPE_NORMAL_ITEM; } }
第三步:在onCreateViewHolder根據viewType返回不同的布局
//創建新View,被LayoutManager所調用 @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { //如果viewType是普通item返回普通的布局,否則是底部布局并返回 if (viewType == TYPE_NORMAL_ITEM) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout .cardview_recyclerview_item, viewGroup, false); final NormalItmeViewHolder vh = new NormalItmeViewHolder(view); if (mClickListener != null) { vh.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mClickListener.onItemClick(vh.itemView, vh.getLayoutPosition()); } }); } return vh; } else { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout .recyclerview_footer_view, viewGroup, false); FooterViewHolder vh = new FooterViewHolder(view); return vh; } }
第四步:根據holder類型判斷數據
//將數據與界面進行綁定的操作 @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { if (viewHolder instanceof NormalItmeViewHolder) { ((NormalItmeViewHolder) viewHolder).titleTv.setText(list.get(position).getTitle()); ((NormalItmeViewHolder) viewHolder).contentTv.setText(list.get(position).getContent()); } else if (viewHolder instanceof FooterViewHolder) { FooterViewHolder footViewHolder = (FooterViewHolder) viewHolder; switch (load_more_status) { case PULLUP_LOAD_MORE: footViewHolder.foot_view_item_tv.setVisibility(View.VISIBLE); footViewHolder.foot_view_item_tv.setText("上拉加載更多"); footViewHolder.pb.setVisibility(View.GONE); break; case LOADING_MORE: footViewHolder.foot_view_item_tv.setVisibility(View.GONE); footViewHolder.pb.setVisibility(View.VISIBLE); break; } } }
到這里,關于上拉更多基本就配置完了。一會完整adapter我會貼出來的。先看效果圖,如下:
Adapter的全部代碼如下:
public class PullMoreRecyclerAdapter extends RecyclerView.Adapter{ private static final int TYPE_NORMAL_ITEM = 0; //普通Item private static final int TYPE_FOOTER_ITEM = 1; //底部FooterView //上拉加載更多 public static final int PULLUP_LOAD_MORE = 1; //正在加載中 public static final int LOADING_MORE = 2; //默認為0 private int load_more_status = 0; public List list; private OnItemClickListener mClickListener; public PullMoreRecyclerAdapter(List list) { this.list = list; } //創建新View,被LayoutManager所調用 @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { //如果viewType是普通item返回普通的布局,否則是底部布局并返回 if (viewType == TYPE_NORMAL_ITEM) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout .cardview_recyclerview_item, viewGroup, false); final NormalItmeViewHolder vh = new NormalItmeViewHolder(view); if (mClickListener != null) { vh.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mClickListener.onItemClick(vh.itemView, vh.getLayoutPosition()); } }); } return vh; } else { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout .recyclerview_footer_view, viewGroup, false); FooterViewHolder vh = new FooterViewHolder(view); return vh; } } //將數據與界面進行綁定的操作 @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { if (viewHolder instanceof NormalItmeViewHolder) { ((NormalItmeViewHolder) viewHolder).titleTv.setText(list.get(position).getTitle()); ((NormalItmeViewHolder) viewHolder).contentTv.setText(list.get(position).getContent()); } else if (viewHolder instanceof FooterViewHolder) { FooterViewHolder footViewHolder = (FooterViewHolder) viewHolder; switch (load_more_status) { case PULLUP_LOAD_MORE: footViewHolder.foot_view_item_tv.setVisibility(View.VISIBLE); footViewHolder.foot_view_item_tv.setText("上拉加載更多"); footViewHolder.pb.setVisibility(View.GONE); break; case LOADING_MORE: footViewHolder.foot_view_item_tv.setVisibility(View.GONE); footViewHolder.pb.setVisibility(View.VISIBLE); break; } } } @Override public int getItemCount() { //+1是加入底部的加載布局項 return list.size() + 1; } public int getItemViewType(int position) { // 如果position+1等于整個布局所有數總和就是底部布局 if (position + 1 == getItemCount()) { return TYPE_FOOTER_ITEM; } else { return TYPE_NORMAL_ITEM; } } //自定義的ViewHolder,持有每個Item的的所有界面元素 public static class NormalItmeViewHolder extends RecyclerView.ViewHolder { public TextView titleTv, contentTv; public ImageView iv; public NormalItmeViewHolder(View view) { super(view); titleTv = (TextView) view.findViewById(R.id.item_title_tv); contentTv = (TextView) view.findViewById(R.id.item_content_tv); iv = (ImageView) view.findViewById(R.id.item_iv); } } /** * 底部FooterView布局 */ public static class FooterViewHolder extends RecyclerView.ViewHolder { public TextView foot_view_item_tv; public ProgressBar pb; public FooterViewHolder(View view) { super(view); pb = (ProgressBar) view.findViewById(R.id.progress_view); foot_view_item_tv = (TextView) view.findViewById(R.id.tv_content); } } public void setMoreStatus(int status){ load_more_status=status; notifyDataSetChanged(); } public void setOnItemClickListener(OnItemClickListener listener) { mClickListener = listener; } public interface OnItemClickListener { public void onItemClick(View itemView, int pos); } }
Activity中的代碼如下:
public class CardViewActivity extends BaseActivity { private RecyclerView rv; private SwipeRefreshLayout swipeRefreshWidget; private PullMoreRecyclerAdapter adapter; private LinearLayoutManager mLayoutManager; ListCardView CardView介紹list = new ArrayList (); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_card_view); rv = (RecyclerView) findViewById(R.id.rv); swipeRefreshWidget = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_widget); swipeRefreshWidget.setColorSchemeResources(R.color.colorAccent, R.color.add_bg_color, R .color.colorPrimary, R.color.colorPrimaryDark, R.color.add_selected_color); //創建默認的線性LayoutManager mLayoutManager = new LinearLayoutManager(this); rv.setLayoutManager(mLayoutManager); //創建并設置Adapter adapter = new PullMoreRecyclerAdapter(getDatas()); rv.setAdapter(adapter); swipeRefreshWidget.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { swipeRefreshWidget.setEnabled(false); new Handler().postDelayed(new Runnable() { @Override public void run() { list.clear(); getDatas(); adapter.notifyDataSetChanged(); swipeRefreshWidget.setEnabled(true); swipeRefreshWidget.setRefreshing(false); } }, 2000); } }); rv.addOnScrollListener(new RecyclerView.OnScrollListener() { private int lastVisibleItem; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == adapter .getItemCount()) { adapter.setMoreStatus(PullMoreRecyclerAdapter.LOADING_MORE); new Handler().postDelayed(new Runnable() { @Override public void run() { getDatas(); adapter.setMoreStatus(PullMoreRecyclerAdapter.PULLUP_LOAD_MORE); adapter.notifyDataSetChanged(); } }, 2000); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); lastVisibleItem = mLayoutManager.findLastVisibleItemPosition(); } }); } private List getDatas() { for (int i = 0; i < 10; i++) { CardInfo ci = new CardInfo(); ci.setContent("美女說:非著名程序員公眾號是東半球最好的技術分享公眾號"); ci.setTitle("非著名程序員" + i); list.add(ci); } return list; } }
CardView是Android5.0之后為新增的控件,CardView是一個卡片布局,布局可以包含圓角和陰影,本質上CardView是一個FrameLayout,因此它作為一個布局容器,可以布局其他的View。
CardView屬性CardView中常用的屬性有:
cardElevation:設置陰影的大小
cardBackgroundColor:卡片布局的背景顏色
cardCornerRadius:卡片布局的圓角的大小
conentPadding:卡片布局和內容之間的距離
效果圖和實例代碼效果圖如下:
代碼如下:
最后友情提醒一下,使用CardView別忘了添加依賴:
compile "com.android.support:cardview-v7:23.4.0"
demo的github地址:https://github.com/loonggg/MaterialDesignDemo 去star吧,我會慢慢完善的。
歡迎關注微信公眾號:非著名程序員(smart_android),每天每周定時推送原創技術文章。所有技術文章, 均會在微信訂閱號首發,關注微信公眾號可以及時獲得技術文章推送。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64889.html
摘要:原圖加載毛玻璃的效果比較快,你的這個打開白屏好幾秒。這就是系列第六篇之系列之,等。這個系列的講解和實例都會整理在一個里,的地址去吧,我會慢慢完善的。 這篇文章其實我一直在想,是寫還是不寫,因為關于講 CoordinatorLayout,AppBarLayout,CollapsingToolbarLayout,Toolbar,TabLayout 等這些控件的使用,以前寫過一篇,那就是《通...
閱讀 3621·2021-09-30 09:59
閱讀 2229·2021-09-13 10:34
閱讀 576·2019-08-30 12:58
閱讀 1507·2019-08-29 18:42
閱讀 2198·2019-08-26 13:44
閱讀 2922·2019-08-23 18:12
閱讀 3321·2019-08-23 15:10
閱讀 1625·2019-08-23 14:37