recycleview支持添加任意view

pull/21/head
fengyuecanzhu 3 years ago
parent 610557bada
commit aa052a8816
  1. 46
      app/src/main/java/xyz/fycz/myreader/base/adapter/BaseListAdapter.java
  2. 26
      app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java
  3. 19
      app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java
  4. 39
      app/src/main/java/xyz/fycz/myreader/ui/fragment/FindBook2Fragment.java
  5. 5
      app/src/main/res/layout/activity_user_info.xml

@ -1,11 +1,13 @@
package xyz.fycz.myreader.base.adapter; package xyz.fycz.myreader.base.adapter;
import android.os.Handler; import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList; import java.util.ArrayList;
@ -20,17 +22,34 @@ import java.util.List;
public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable { public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private static final String TAG = "BaseListAdapter"; private static final String TAG = "BaseListAdapter";
protected static final int TYPE_OTHER = Integer.MIN_VALUE;
/*common statement*/ /*common statement*/
protected List<T> mList = new ArrayList<>(); protected List<T> mList = new ArrayList<>();
protected SparseArray<View> otherViews = new SparseArray<>();
protected SparseIntArray otherViewPos = new SparseIntArray();
protected OnItemClickListener mClickListener; protected OnItemClickListener mClickListener;
protected OnItemLongClickListener mLongClickListener; protected OnItemLongClickListener mLongClickListener;
/************************abstract area************************/ /************************abstract area************************/
protected abstract IViewHolder<T> createViewHolder(int viewType); protected abstract IViewHolder<T> createViewHolder(int viewType);
/*************************rewrite logic area***************************************/ /*************************rewrite logic area***************************************/
@Override
public int getItemViewType(int position) {
int key = otherViewPos.indexOfKey(position);
if (key >= 0) {
return otherViewPos.valueAt(key);
}
return super.getItemViewType(position);
}
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType < TYPE_OTHER + getOtherCount()) {
return new OtherViewHolder(otherViews.get(viewType));
}
IViewHolder<T> viewHolder = createViewHolder(viewType); IViewHolder<T> viewHolder = createViewHolder(viewType);
View view = viewHolder.createItemView(parent); View view = viewHolder.createItemView(parent);
@ -41,6 +60,7 @@ public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerVi
@Override @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof OtherViewHolder) return;
//防止别人直接使用RecyclerView.ViewHolder调用该方法 //防止别人直接使用RecyclerView.ViewHolder调用该方法
if (!(holder instanceof BaseViewHolder)) if (!(holder instanceof BaseViewHolder))
throw new IllegalArgumentException("The ViewHolder item must extend BaseViewHolder"); throw new IllegalArgumentException("The ViewHolder item must extend BaseViewHolder");
@ -76,6 +96,10 @@ public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerVi
return mList.size(); return mList.size();
} }
public int getOtherCount() {
return otherViews.size();
}
@Override @Override
public Filter getFilter() { public Filter getFilter() {
return null; return null;
@ -109,6 +133,13 @@ public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerVi
notifyItemInserted(index); notifyItemInserted(index);
} }
public synchronized void addOther(int index, View view) {
int type = TYPE_OTHER + getOtherCount();
otherViews.put(type, view);
otherViewPos.put(index, type);
notifyItemInserted(index);
}
public synchronized void addItems(List<T> values) { public synchronized void addItems(List<T> values) {
int oldSize = getItemSize(); int oldSize = getItemSize();
if (mList.addAll(values)) { if (mList.addAll(values)) {
@ -122,7 +153,7 @@ public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerVi
public synchronized void removeItem(T value) { public synchronized void removeItem(T value) {
int pos = mList.indexOf(value); int pos = mList.indexOf(value);
if (mList.remove(value)){ if (mList.remove(value)) {
notifyItemRemoved(pos); notifyItemRemoved(pos);
if (pos != mList.size()) if (pos != mList.size())
notifyItemRangeChanged(pos, mList.size() - pos); notifyItemRangeChanged(pos, mList.size() - pos);
@ -135,9 +166,9 @@ public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerVi
} }
} }
public synchronized void swapItem(int oldPos, int newPos){ public synchronized void swapItem(int oldPos, int newPos) {
int size = getItemSize(); int size = getItemSize();
if (oldPos >= 0 && oldPos < size && newPos >=0 && newPos < size){ if (oldPos >= 0 && oldPos < size && newPos >= 0 && newPos < size) {
Collections.swap(mList, oldPos, newPos); Collections.swap(mList, oldPos, newPos);
notifyItemMoved(oldPos, newPos); notifyItemMoved(oldPos, newPos);
} }
@ -174,4 +205,11 @@ public abstract class BaseListAdapter<T> extends RecyclerView.Adapter<RecyclerVi
public interface OnItemLongClickListener { public interface OnItemLongClickListener {
boolean onItemLongClick(View view, int pos); boolean onItemLongClick(View view, int pos);
} }
static class OtherViewHolder extends RecyclerView.ViewHolder {
public OtherViewHolder(@NonNull View itemView) {
super(itemView);
}
}
} }

@ -35,6 +35,10 @@ public class AdConfig {
private AdBean detail; private AdBean detail;
//搜索页广告配置 //搜索页广告配置
private AdBean search; private AdBean search;
//阅读页广告配置
private AdBean read;
//发现页广告配置
private AdBean find;
public AdConfig() { public AdConfig() {
} }
@ -138,6 +142,28 @@ public class AdConfig {
this.search = search; this.search = search;
} }
public AdBean getRead() {
if (read == null) {
read = new AdBean(0, 60);
}
return read;
}
public void setRead(AdBean read) {
this.read = read;
}
public AdBean getFind() {
if (find == null) {
find = new AdBean(0, 60);
}
return find;
}
public void setFind(AdBean find) {
this.find = find;
}
public boolean isSubSource() { public boolean isSubSource() {
return subSource; return subSource;
} }

@ -61,10 +61,12 @@ import xyz.fycz.myreader.application.SysManager;
import xyz.fycz.myreader.base.BaseActivity; import xyz.fycz.myreader.base.BaseActivity;
import xyz.fycz.myreader.base.BitIntentDataManager; import xyz.fycz.myreader.base.BitIntentDataManager;
import xyz.fycz.myreader.base.observer.MyObserver; import xyz.fycz.myreader.base.observer.MyObserver;
import xyz.fycz.myreader.base.observer.MySingleObserver;
import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.common.URLCONST; import xyz.fycz.myreader.common.URLCONST;
import xyz.fycz.myreader.databinding.ActivityReadBinding; import xyz.fycz.myreader.databinding.ActivityReadBinding;
import xyz.fycz.myreader.entity.Setting; import xyz.fycz.myreader.entity.Setting;
import xyz.fycz.myreader.entity.ad.AdBean;
import xyz.fycz.myreader.enums.Font; import xyz.fycz.myreader.enums.Font;
import xyz.fycz.myreader.enums.LocalBookSource; import xyz.fycz.myreader.enums.LocalBookSource;
import xyz.fycz.myreader.greendao.DbManager; import xyz.fycz.myreader.greendao.DbManager;
@ -101,6 +103,7 @@ import xyz.fycz.myreader.util.help.DateHelper;
import xyz.fycz.myreader.util.help.StringHelper; import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.notification.NotificationClickReceiver; import xyz.fycz.myreader.util.notification.NotificationClickReceiver;
import xyz.fycz.myreader.util.notification.NotificationUtil; import xyz.fycz.myreader.util.notification.NotificationUtil;
import xyz.fycz.myreader.util.utils.AdUtils;
import xyz.fycz.myreader.util.utils.ColorUtil; import xyz.fycz.myreader.util.utils.ColorUtil;
import xyz.fycz.myreader.util.utils.FileUtils; import xyz.fycz.myreader.util.utils.FileUtils;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
@ -576,6 +579,22 @@ public class ReadActivity extends BaseActivity<ActivityReadBinding> implements C
//保存最近阅读时间 //保存最近阅读时间
mBook.setLastReadTime(DateHelper.getLongDate()); mBook.setLastReadTime(DateHelper.getLongDate());
init(); init();
initAd();
}
private void initAd() {
AdUtils.checkHasAd().subscribe(new MySingleObserver<Boolean>() {
@Override
public void onSuccess(@NonNull Boolean aBoolean) {
AdBean adBean = AdUtils.getAdConfig().getRead();
if (aBoolean && AdUtils.adTime("read", adBean)) {
if (adBean.getStatus() > 0) {
AdUtils.showInterAd(ReadActivity.this, "read");
}
}
}
});
} }

@ -2,6 +2,7 @@ package xyz.fycz.myreader.ui.fragment;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -21,17 +22,21 @@ import xyz.fycz.myreader.base.LazyFragment;
import xyz.fycz.myreader.base.adapter.BaseListAdapter; import xyz.fycz.myreader.base.adapter.BaseListAdapter;
import xyz.fycz.myreader.base.adapter.IViewHolder; import xyz.fycz.myreader.base.adapter.IViewHolder;
import xyz.fycz.myreader.base.observer.MyObserver; import xyz.fycz.myreader.base.observer.MyObserver;
import xyz.fycz.myreader.base.observer.MySingleObserver;
import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.databinding.FragmentFindBook2Binding; import xyz.fycz.myreader.databinding.FragmentFindBook2Binding;
import xyz.fycz.myreader.entity.FindKind; import xyz.fycz.myreader.entity.FindKind;
import xyz.fycz.myreader.entity.ad.AdBean;
import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Book;
import xyz.fycz.myreader.greendao.service.BookService; import xyz.fycz.myreader.greendao.service.BookService;
import xyz.fycz.myreader.ui.activity.BookDetailedActivity; import xyz.fycz.myreader.ui.activity.BookDetailedActivity;
import xyz.fycz.myreader.ui.activity.BookstoreActivity; import xyz.fycz.myreader.ui.activity.BookstoreActivity;
import xyz.fycz.myreader.ui.activity.ReadActivity;
import xyz.fycz.myreader.ui.adapter.holder.FindBookHolder; import xyz.fycz.myreader.ui.adapter.holder.FindBookHolder;
import xyz.fycz.myreader.ui.dialog.SourceExchangeDialog; import xyz.fycz.myreader.ui.dialog.SourceExchangeDialog;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.help.StringHelper; import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.utils.AdUtils;
import xyz.fycz.myreader.util.utils.RxUtils; import xyz.fycz.myreader.util.utils.RxUtils;
import xyz.fycz.myreader.webapi.BookApi; import xyz.fycz.myreader.webapi.BookApi;
import xyz.fycz.myreader.webapi.crawler.base.FindCrawler; import xyz.fycz.myreader.webapi.crawler.base.FindCrawler;
@ -51,6 +56,8 @@ public class FindBook2Fragment extends LazyFragment {
private static final String KIND = "kind"; private static final String KIND = "kind";
private static final String FIND_CRAWLER = "findCrawler"; private static final String FIND_CRAWLER = "findCrawler";
private AdBean adBean;
private View flow;
public FindBook2Fragment() { public FindBook2Fragment() {
} }
@ -78,6 +85,7 @@ public class FindBook2Fragment extends LazyFragment {
outState.putString(APPCONST.DATA_KEY, dataKey); outState.putString(APPCONST.DATA_KEY, dataKey);
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
} }
@Override @Override
public void lazyInit() { public void lazyInit() {
initData(); initData();
@ -92,6 +100,8 @@ public class FindBook2Fragment extends LazyFragment {
} }
protected void initData() { protected void initData() {
adBean = AdUtils.getAdConfig().getFind();
getFlow();
findBookAdapter = new BaseListAdapter<Book>() { findBookAdapter = new BaseListAdapter<Book>() {
@Override @Override
protected IViewHolder<Book> createViewHolder(int viewType) { protected IViewHolder<Book> createViewHolder(int viewType) {
@ -104,6 +114,19 @@ public class FindBook2Fragment extends LazyFragment {
loadBooks(); loadBooks();
} }
private void getFlow() {
AdUtils.checkHasAd().subscribe(new MySingleObserver<Boolean>() {
@Override
public void onSuccess(@NonNull Boolean aBoolean) {
if (aBoolean && AdUtils.adTime("find", adBean)) {
if (adBean.getStatus() > 0) {
AdUtils.getFlowAd(getActivity(), 1, view -> flow = view, "find");
}
}
}
});
}
protected void initWidget() { protected void initWidget() {
binding.loading.setOnReloadingListener(() -> { binding.loading.setOnReloadingListener(() -> {
page = 1; page = 1;
@ -156,6 +179,13 @@ public class FindBook2Fragment extends LazyFragment {
} else { } else {
findBookAdapter.refreshItems(books); findBookAdapter.refreshItems(books);
binding.srlFindBooks.finishRefresh(); binding.srlFindBooks.finishRefresh();
if (flow != null) {
int index = findBookAdapter.getItemCount() - books.size() + 2;
index = Math.min(findBookAdapter.getItemCount() - 1, index);
findBookAdapter.addOther(index, flow);
flow = null;
getFlow();
}
} }
} else { } else {
if (books.size() == 0) { if (books.size() == 0) {
@ -163,6 +193,13 @@ public class FindBook2Fragment extends LazyFragment {
} else { } else {
findBookAdapter.addItems(books); findBookAdapter.addItems(books);
binding.srlFindBooks.finishLoadMore(); binding.srlFindBooks.finishLoadMore();
if (flow != null) {
int index = findBookAdapter.getItemCount() - books.size() + 2;
index = Math.min(findBookAdapter.getItemCount() - 1, index);
findBookAdapter.addOther(index, flow);
flow = null;
getFlow();
}
} }
} }
page++; page++;
@ -176,7 +213,7 @@ public class FindBook2Fragment extends LazyFragment {
binding.loading.showError(); binding.loading.showError();
binding.srlFindBooks.finishRefresh(); binding.srlFindBooks.finishRefresh();
} else { } else {
if (e.getMessage()!= null && e.getMessage().contains("没有下一页")) { if (e.getMessage() != null && e.getMessage().contains("没有下一页")) {
binding.srlFindBooks.finishLoadMoreWithNoMoreData(); binding.srlFindBooks.finishLoadMoreWithNoMoreData();
} else { } else {
ToastUtils.showError("数据加载失败\n" + e.getLocalizedMessage()); ToastUtils.showError("数据加载失败\n" + e.getLocalizedMessage());

@ -46,7 +46,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary" android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" /> android:textSize="@dimen/text_normal_size" />
</RelativeLayout> </RelativeLayout>
@ -74,7 +73,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary" android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" /> android:textSize="@dimen/text_normal_size" />
</RelativeLayout> </RelativeLayout>
@ -102,7 +100,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary" android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" /> android:textSize="@dimen/text_normal_size" />
</RelativeLayout> </RelativeLayout>
@ -179,7 +176,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary" android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" /> android:textSize="@dimen/text_normal_size" />
</RelativeLayout> </RelativeLayout>
@ -207,7 +203,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary" android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" android:textSize="@dimen/text_normal_size"
android:layout_toStartOf="@+id/iv_no_ad_arrow"/> android:layout_toStartOf="@+id/iv_no_ad_arrow"/>

Loading…
Cancel
Save