问题
I am working with a recyclerView and i succeeded in inflating two views but each view content comes from different json data types. i tried passing the two datatypes in the adapter but they are not properly binded
source code
public class SimpleStringRecyclerViewAdapter : RecyclerView.Adapter {
private Article[] mValues; private List<YouTubeItem> mValues2; Context context; public SimpleStringRecyclerViewAdapter(Context context, Article[] items, List<YouTubeItem> item ) { this.context = context; mValues = items; mValues2 = item; } public override int ItemCount { get { return mValues.Count() + mValues2.Count(); } } public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder is SimpleViewHolder) try { Article item = mValues[position]; var simpleHolder = holder as SimpleViewHolder; simpleHolder.mTxtView.Text = Android.Text.Html.FromHtml(item.Title).ToString(); simpleHolder.mTxtView2.Text = item.Description; using (var imageView = simpleHolder.mImageView) { string url = Android.Text.Html.FromHtml(item.UrlToImage).ToString(); //Download and display image UrlImageViewHelper.SetUrlDrawable(imageView, url, Resource.Drawable.cheese_1 ); } // simpleHolder.mprogressbar.Visibility = ViewStates.Gone; } catch (Exception e) { //Toast.MakeText(this.context, e.ToString(), ToastLength.Long).Show(); } else { try { YouTubeItem item = mValues2[position]; var simpleHolder = holder as SimpleViewHolder2; simpleHolder.mTxtView.Text = Android.Text.Html.FromHtml(item.Title).ToString(); // simpleHolder.mTxtView2.Text = item.DescriptionShort; using (var imageView = simpleHolder.mImageView) { string url = Android.Text.Html.FromHtml(item.MaxResThumbnailUrl).ToString(); //Download and display image UrlImageViewHelper.SetUrlDrawable(imageView, url, Resource.Drawable.cheese_1 ); } } catch (Exception e) { //Toast.MakeText(this.context, e.ToString(), ToastLength.Long).Show(); } } } public override int GetItemViewType(int position) { if ((position % 2) == 0) { //Even number return Resource.Layout.List_Item; } else { //Odd number return Resource.Layout.VideoList; } } public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == Resource.Layout.List_Item) { View view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.List_Item, parent, false); view.SetBackgroundColor(Color.White); SimpleViewHolder holder = new SimpleViewHolder(view); // holder.mprogressbar = view.FindViewById<ProgressBar>(Resource.Id.progressBar); // holder.mprogressbar.Visibility = ViewStates.Visible; //Showing loading progressbar return holder; } else { View view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.VideoList, parent, false); view.SetBackgroundColor(Color.White); SimpleViewHolder2 holder = new SimpleViewHolder2(view); return holder; } }
}
public class SimpleViewHolder : RecyclerView.ViewHolder { public string mBoundString; public readonly View mView; public readonly ImageView mImageView; public readonly TextView mTxtView; public readonly TextView mTxtView2; // public ProgressBar mprogressbar;
public SimpleViewHolder(View view) : base(view) { mView = view; mImageView = view.FindViewById<ImageView>(Resource.Id.avatar); mTxtView = view.FindViewById<TextView>(Resource.Id.Text1); mTxtView2 = view.FindViewById<TextView>(Resource.Id.Text2); // mprogressbar = view.FindViewById<ProgressBar>(Resource.Id.progressBar); } public override string ToString() { return base.ToString() + " '" + mTxtView.Text; }
} public class SimpleViewHolder2 : RecyclerView.ViewHolder { public string mBoundString; public readonly View mView; public readonly ImageView mImageView; public readonly TextView mTxtView; public readonly TextView mTxtView2;
public SimpleViewHolder2(View view) : base(view) { mView = view; mImageView = view.FindViewById<ImageView>(Resource.Id.videoavatar); mTxtView = view.FindViewById<TextView>(Resource.Id.videoText1); // mprogressbar = view.FindViewById<ProgressBar>(Resource.Id.progressBar); }
回答1:
You should merge data to one data source only. You can try this way:
Create data source class
public class Data { int type; // 1 is article and 2 is youtubeitem public Article article; public YouTubeItem youTubeItem; }
Now merge two data source to only one
public List<Data> merge(Articel[] articles, List<YouTubeItem> items) { List<Data> datas = new ArrayList<>(); for(Article article : articles) { Data data = new Data(); data.article = article; data.youTubeItem = null; data.type = 1; datas.add(data); } for(YouTubeItem item : items) { Data data = new Data(); data.article = null; data.youTubeItem = item; data.type = 2; datas.add(data); } return datas; }
Change constructor of adapter
private List<Data> datas; public SimpleStringRecyclerViewAdapter(Context context, List<Data> datas ) { this.datas = datas; }
Change get Item count
public override int ItemCount { get { return datas.Count(); } }
Change getViewType
public override int GetItemViewType(int position) { if (datas.get(position).type == 1) { return Resource.Layout.List_Item; } else { return Resource.Layout.VideoList; } }
EDITED: For merge random method
public List<Data> mergeRandom(Articel[] articles, List<YouTubeItem> items) {
List<Data> datas = new ArrayList<>();
List<Integer> random = new ArrayList<>();
int maxLength = articles.length + items.size();
for(int i = 0; i< maxLength; i++) {
random.add(i);
}
while (random.size() > 0) {
// get random item
int index = new Random().nextInt(random.size());
int position = random.get(index);
if(position <= article.length - 1) {
Data data = new Data();
data.article = articles[position];
data.youTubeItem = null;
data.type = 1;
datas.add(data);
} else {
Data data = new Data();
data.article = null;
data.youTubeItem = items.get(position - article.length);
data.type = 2;
datas.add(data);
}
random.remove(index);
}
return datas;
}
For merge odd&even method
List<Data> mergeOddEven(Articel[] articles, List<YouTubeItem> items) {
List<Data> datas = new ArrayList<>();
int articleIndex = 0;
int youtubeIndex = 0;
int length = articles.length + items.size();
for(int i = 0; i< length; i++) {
if(articleIndex >= articles.length || youtubeIndex >= items.size()) {
if(articleIndex < articles.length) {
for(int j = articleIndex; j < articles.length ; j++) {
Data data = new Data();
data.article = articles[j];
data.youTubeItem = null;
data.type = 1;
datas.add(data);
}
} else {
for(int j = youtubeIndex; j < items.size() ; j++) {
Data data = new Data();
data.article = null;
data.youTubeItem = items.get(j);
data.type = 2;
datas.add(data);
}
}
break;
}
if(i % 2 == 0) {
Data data = new Data();
data.article = articles[articleIndex];
data.youTubeItem = null;
data.type = 1;
datas.add(data);
articleIndex++;
} else {
Data data = new Data();
data.article = null;
data.youTubeItem = tems.get(youtubeIndex);
data.type = 2;
datas.add(data);
youtubeIndex++;
}
}
return datas;
}
Hope it help
回答2:
use this function to merge the data and use this in your adapter :
public List<Data> merge(Articel[] articles, List<YouTubeItem> items) {
int counter = 0,counter1=0,size=0;
size = articles.length + items.size();
List<Data> datas = new ArrayList<>();
for (int i = 0; i < size;i++) {
if (i % 2 == 0) {
if(counter1<articles.length){
Article article = articles[counter1];
Data data = new Data();
data.article = article;
data.youTubeItem = null;
data.type = 1;
datas.add(data);
counter1++;
}else if(counter<items.size()){
YouTubeItem item = items.get(counter);
Data data = new Data();
data.article = null;
data.youTubeItem = item;
data.type = 2;
datas.add(data);
counter++;
}
} else {
if(counter<items.size()){
YouTubeItem item = items.get(counter);
Data data = new Data();
data.article = null;
data.youTubeItem = item;
data.type = 2;
datas.add(data);
counter++;
}else if(counter1<articles.length){
Article article = articles[counter1];
Data data = new Data();
data.article = article;
data.youTubeItem = null;
data.type = 1;
datas.add(data);
counter1++;
}
}
}
return datas;
}
回答3:
Make one interface
to implement your data pojo class like below..
public interface Parent{
}
Then pojo class like
public class User implements Parent{
private String name,addres;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddres() {
return addres;
}
public void setAddres(String addres) {
this.addres = addres;
}
}
Then add all the data into parent list and bind into adapter .. Adapter bind data according to pojo class like below..
public class SearchListAdapter extends ArrayAdapter<Parent> {
Context context;
Parent parent[] = null;
public SearchListAdapter(Context context, int layoutResourceId, Parent[] parent) {
super(context, layoutResourceId, parent);
this.context = context;
this.parent = parent;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final LayoutInflater inflater = ((Activity) context).getLayoutInflater();
final View outerContainer = inflater.inflate(R.layout.food_list_item, parent, false);
if (this.parent != null) {
Parent temp = this.parent[position];
if (temp instanceof FoodItem) {
final FoodItem item = (FoodItem) temp;
}
}
}
}
来源:https://stackoverflow.com/questions/49853500/recyclerview-with-multiple-view-types-and-data-source