我正在尝试学习Android,并且这样做已经构建了一个新闻Feed应用程序。我使用了Android应用程序架构和分页来在recyclerview中显示feed。
以下是我的适配器
public class NewsAdapter extends PagedListAdapter<NewsFeed, RecyclerView.ViewHolder>{
private Context mContext;
private static final int NEWS = 0;
private static final int NATIVE_AD = 1;
public NewsAdapter(Context context, boolean twoPane){
super(DIFF_CALLBACK);
mContext = context;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if(viewType == NEWS){
CardView view = (CardView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.feed_list_item, parent, false);
return new NewsViewHolder(view);
}
if(viewType == NATIVE_AD) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_native_ad, parent, false);
return new NativeAdViewHolder(view);
}
return null;
// View view = LayoutInflater.from(parent.getContext())
// .inflate(R.layout.feed_list_item, parent, false);
//
// return new NewsViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
NewsFeed news = getItem(position);
if(news.getNativeAd() == null){
NewsViewHolder newsViewHolder = (NewsViewHolder) holder;
if (news != null) {
newsViewHolder.bindTo(news);
} else {
newsViewHolder.clear();
}
}else{
NativeAdViewHolder nativeAdViewHolder = (NativeAdViewHolder) holder;
NativeAd nativeAd = (NativeAd) getItem(position).getNativeAd();
ImageView adImage = nativeAdViewHolder.adImage;
TextView tvAdTitle = nativeAdViewHolder.tvAdTitle;
TextView tvAdBody = nativeAdViewHolder.tvAdBody;
Button btnCTA = nativeAdViewHolder.btnCTA;
LinearLayout adChoicesContainer = nativeAdViewHolder.adChoicesContainer;
MediaView mediaView = nativeAdViewHolder.mediaView;
tvAdTitle.setText(nativeAd.getAdTitle());
tvAdBody.setText(nativeAd.getAdBody());
NativeAd.downloadAndDisplayImage(nativeAd.getAdIcon(), adImage);
btnCTA.setText(nativeAd.getAdCallToAction());
AdChoicesView adChoicesView = new AdChoicesView(mContext, nativeAd, true);
adChoicesContainer.addView(adChoicesView);
mediaView.setNativeAd(nativeAd);
List<View> clickableViews = new ArrayList<>();
clickableViews.add(adImage);
clickableViews.add(btnCTA);
clickableViews.add(mediaView);
nativeAd.registerViewForInteraction(nativeAdViewHolder.container, clickableViews);
}
}
@Override
public int getItemViewType(int position) {
NewsFeed item = getItem(position);
if(item.getNativeAd() == null){
return NEWS;
}
return NATIVE_AD;
// return super.getItemViewType(position);
}
public static final DiffUtil.ItemCallback<NewsFeed> DIFF_CALLBACK =
new DiffUtil.ItemCallback<NewsFeed>() {
@Override
public boolean areItemsTheSame(NewsFeed oldItem, NewsFeed newItem) {
return oldItem.getTitle() == newItem.getTitle();
}
@Override
public boolean areContentsTheSame(NewsFeed oldItem, NewsFeed newItem) {
return oldItem.equals(newItem);
}
};
public class NewsViewHolder extends RecyclerView.ViewHolder {
private View itemView;
private ImageView newsImage;
private TextView title;
private TextView description;
public NewsViewHolder(View itemView){
super(itemView);
this.itemView = itemView;
this.newsImage = (ImageView) itemView.findViewById(R.id.news_icon);
this.title = (TextView) itemView.findViewById(R.id.tv_feed_title);
this.description = (TextView) itemView.findViewById(R.id.tv_feed_description);
}
public void bindTo(final NewsFeed newsFeed){
if(newsFeed.getUrlToImage() != null) {
Picasso.get().load(newsFeed.getUrlToImage()).into(newsImage);
}
title.setText(newsFeed.getTitle());
description.setText(newsFeed.getDescription());
itemView.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// Toast.makeText(mContext,newsFeed.getTitle(),Toast.LENGTH_LONG).show();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(newsFeed.getUrl()));
mContext.startActivity(browserIntent);
}
});
}
public void clear(){
newsImage.setImageURI(null);
title.setText(null);
}
}
private static class NativeAdViewHolder extends RecyclerView.ViewHolder {
ImageView adImage;
TextView tvAdTitle;
TextView tvAdBody;
Button btnCTA;
View container;
LinearLayout adChoicesContainer;
MediaView mediaView;
NativeAdViewHolder(View itemView) {
super(itemView);
this.container = itemView;
adImage = (ImageView) itemView.findViewById(R.id.adImage);
tvAdTitle = (TextView) itemView.findViewById(R.id.tvAdTitle);
tvAdBody = (TextView) itemView.findViewById(R.id.tvAdBody);
btnCTA = (Button) itemView.findViewById(R.id.btnCTA);
adChoicesContainer = (LinearLayout) itemView.findViewById(R.id.adChoicesContainer);
mediaView = (MediaView) itemView.findViewById(R.id.mediaView);
}
}
public void updateList(NewsFeed newsFeed){
PagedList<NewsFeed> pagedList = this.getCurrentList();
submitList(pagedList);
}
}
我正在使用ViewModel并观察结果以更新适配器。
newsViewModel = ViewModelProviders.of(this).get(NewsViewModel.class);
newsViewModel.setmContext(this);
newsViewModel.dataLoadStatus().observe(this, loadStatus -> {
switch (loadStatus) {
case LOADING:
progressBar.setVisibility(View.VISIBLE);
break;
case LOADED:
progressBar.setVisibility(View.INVISIBLE);
break;
case FAILED:
progressBar.setVisibility(View.INVISIBLE);
break;
}
});
newsViewModel.getNews().observe(this, pagedList ->{
newsAdapter.submitList(pagedList);
});
现在,我正在使用FB原生广告,并希望更新我的recyclerview适配器的pagedList,以便显示添加块(上面的适配器添加了代码)。我无法更新此pagedList或通知适配器查看新数据。 任何人都可以指出我正确的方向。
由于