Android RecyclerView實現載入多樣式子項
RecyclerView實現載入多種Item佈局
前言
好久沒寫部落格,是時候寫寫部落格了,前面一個月都在找實習、學校實訓事情忙都忙不過來,跑完之後還要去反省,今天哪裡沒做對?哪裡還需要完善?自己的知識哪裡還需要鞏固?等等,牢騷話就不發了,步入正題!
背景
最近學校實訓,要完成一個大的V電影的仿製,我就做了,其中涉及到很多的Android知識點,對這個專案感興趣的可以點選這裡 然後看專案的原始碼!這個專案中就涉及到一個知識就是RecyclerView載入多種Item佈局。
正文
首先,我們要明確RecyclerView中載入資料來源的Where,那就是在Adapter介面卡中,既然需要介面卡,當然我們就要重寫介面卡,然後讓其適應我們的資料來源,所以我們需要讓我們的介面卡繼承RecyclerView的Adapter
public class LatestRecyclerAdapter extends RecyclerView.Adapter<>{}
這兒有個尖括號,那說明需要在Adapter中放入泛型,使用過RecyclerView的應該知道,這兒確定了泛型,那就在Adapter中方法的屬性也變成相應的泛型,這樣就會使RecyclerView只能載入一種ViewHolder,也就是一種樣式的子項,所以我們這需要用RecyclerView自帶的ViewHolder,然後在具體方法中進行判斷,根據不同的情況載入不同的佈局,這樣我們就實現載入多種樣式的子項
public class LatestRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {}
既然有多種樣式的子項,所以我們需要針對不同的子項寫ViewHolder,如下
ViewHolder:
class AdverViewHolder extends RecyclerView.ViewHolder { public AdverViewHolder(View itemView) { super(itemView); mContainer = ((ViewPager) itemView.findViewById(R.id.fragment_latest_item_adver_container)); mIndicator = ((RadioGroup) itemView.findViewById(R.id.fragment_latest_item_adver_indicator)); } } class NormalViewHolder extends RecyclerView.ViewHolder { ImageView mNormalImage; TextView mNormalTopic; View mNormalDiving; TextView mNormalTitle; TextView mNormalInfo; public NormalViewHolder(View itemView) { super(itemView); mNormalImage = (ImageView) itemView.findViewById(R.id.fragment_latest_item_normal_img); mNormalTopic = (TextView) itemView.findViewById(R.id.fragment_latest_item_normal_topic); mNormalDiving = itemView.findViewById(R.id.fragment_latest_item_normal_diving); mNormalTitle = (TextView) itemView.findViewById(R.id.fragment_latest_item_normal_title); mNormalInfo = (TextView) itemView.findViewById(R.id.fragment_latest_item_normal_info); } } class LoadViewHolder extends RecyclerView.ViewHolder { ProgressBar progressBar; TextView message; public LoadViewHolder(View itemView) { super(itemView); progressBar = (ProgressBar) itemView.findViewById(R.id.fragment_latest_item_load_progress); message = (TextView) itemView.findViewById(R.id.fragment_latest_item_load_msg); } }
然後我們會在RecyclerView的getItemViewType方法根據不同的情況返回不同的標誌位,例如:
@Override
public int getItemViewType(int position) {
if (position == 0) {
return LatestAdapterParams.ADVER_VIEW;
} else if (position == normalData.size()) {
return LatestAdapterParams.EMPTY_VIEW;
} else {
return super.getItemViewType(position);
}
}
因為我的廣告是第一個位置顯示,所以當position等於0時,就返回一個已賦值的廣告標誌位(ADVER_VIEW),當資料來源顯示完了,說明需要載入資料,所以我又返回的是空標誌位(EMPTY_VIEW)然後在onCreateViewHolder方法中進行判斷標誌位,根據不同的標誌位,我們建立不同的ViewHolder,然後讓ViewHolder與其佈局進行繫結
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == LatestAdapterParams.ADVER_VIEW) {
view = LayoutInflater.from(context).inflate(R.layout.fragment_latest_item_adver, parent, false);
AdverViewHolder adverViewHolder = new AdverViewHolder(view);
mContainer.setAdapter(new FragmentViewPagerAdapter(fManager, getAdverData()));
mContainer.addOnPageChangeListener(this);
mContainer.setOnTouchListener(this);
return adverViewHolder;
} else if (viewType == LatestAdapterParams.EMPTY_VIEW) {
view = LayoutInflater.from(context).inflate(R.layout.fragment_latest_item_load, parent, false);
return new LoadViewHolder(view);
} else {
view = LayoutInflater.from(context).inflate(R.layout.fragment_latest_item_normal, parent, false);
final NormalViewHolder normalViewHolder = new NormalViewHolder(view);
normalViewHolder.mNormalImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = normalViewHolder.getAdapterPosition();
LatestNormalDataBean bean = normalData.get(position - 1);
Intent intent = new Intent(v.getContext(), ItemActivity.class);
Bundle bundle = new Bundle();
bundle.putString("DATA_FROM", AllPageTypeParams.HOME_NORMAL_PAGE);
bundle.putSerializable("NORMAL_DATA", bean);
intent.putExtra("DATA", bundle);
v.getContext().startActivity(intent);
}
});
return normalViewHolder;
}
}
然後具體的實現,就在onBindViewHolder方法中,例如:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof AdverViewHolder) {
mIndicator.removeAllViews();
if (adverData != null) {
for (int i = 0; i < adverData.size(); i++) {
mIndicator.addView(getRadioButton());
}
} else {
for (int i = 0; i < LatestAdapterParams.ADVER_DEFAULT_NUM; i++) {
mIndicator.addView(getRadioButton());
}
}
mContainer.setCurrentItem(1);
RadioButton childOne = ((RadioButton) mIndicator.getChildAt(0));
childOne.setChecked(true);
} else if (holder instanceof NormalViewHolder) {
NormalViewHolder normalViewHolder = (NormalViewHolder) holder;
LatestNormalDataBean normalDataBean = normalData.get(position - 1);
x.image().bind(normalViewHolder.mNormalImage, normalDataBean.getImage());
normalViewHolder.mNormalTitle.setText(normalDataBean.getTitle());
if (normalDataBean.getIs_album() == 0) {
normalViewHolder.mNormalTopic.setVisibility(View.INVISIBLE);
normalViewHolder.mNormalDiving.setVisibility(View.INVISIBLE);
normalViewHolder.mNormalInfo.setText(normalDataBean.getCates().get(0).getCatename() + " / " + normalDataBean.getDuration() / 60 + "'" + normalDataBean.getDuration() % 60 + "''");
} else {
normalViewHolder.mNormalTopic.setVisibility(View.VISIBLE);
normalViewHolder.mNormalDiving.setVisibility(View.VISIBLE);
normalViewHolder.mNormalInfo.setText(normalDataBean.getApp_fu_title());
}
} else if (holder instanceof LoadViewHolder) {
/**
* 上拉載入進度條的介面,其中可以寫載入更多的不同情況
*/
RequestParams requestParams = new RequestParams(HttpRequestParams.HOST_URL + HttpRequestParams.LATEST_NORMAL_PATH + "?p=" + LatestAdapterParams.NORMAL_PAGE_NUM);
x.http().get(requestParams, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
Gson gson = new Gson();
LatestNormalBean latestNormalBean = gson.fromJson(result, LatestNormalBean.class);
List<LatestNormalDataBean> normalDataBeen = latestNormalBean.getData();
updateLatestNormalData(normalDataBeen);
++LatestAdapterParams.NORMAL_PAGE_NUM;
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
}
如果想看具體的程式碼,請點選這裡
圖片如下
最後我想說的,你可以借鑑下這位小哥的部落格,我的程式碼中涉及到了xUtils框架、點選事件等無關程式碼,所以有可能程式碼有點多和繁瑣!