我知道標題有點奇怪,對不起。這是一個奇怪的問題,我什至不確定我能否正確解釋它,這是我的嘗試:
基本上我想為任何擴展RecyclerView.Adapter<RecyclerView.ViewHolder> 的配接器實作一個包裝器,如果需要,包裝器最終將能夠插入行,并且它會根據需要進行修改getItemCount(),但我還沒有接近那個部分。
這是我的類定義:
class MyRecyclerAdapterWrapper(activity: Activity,val originalAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
我將要包裝的原始配接器傳遞給它。
如果我有這樣的類定義,然后我嘗試創建這樣的實體MyRecyclerAdapterWrapper:
val wrapper = MyRecyclerAdapterWrapper(activity, myOriginalAdapter)
myOriginalAdapter一個實體在哪里:
class MyOriginalAdapter() : RecyclerView.Adapter<MyOriginalAdapter.MyViewHolder>() {
然后我收到一個錯誤,說它正在期待RecyclerView.Adapter<RecyclerView.ViewHolder> ,但得到了MyOriginalAdapter.
所以我out在類定義上嘗試了這樣的關鍵字:
class MyRecyclerAdapterWrapper(activity: Activity,val originalAdapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
這允許我的建構式呼叫MyRecyclerAdapterWrapper(activity, myOriginalAdapter)停止抱怨,但是我的MyRecyclerAdapterWrapper類無法實作一些RecyclerView.Adapter<RecyclerView.ViewHolder>覆寫,因為originalAdapter期望Nothing而不是RecyclerView.ViewHolder.
例如里面MyRecyclerAdapterWrapper我有這段代碼:
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
originalAdapter.onBindViewHolder(holder,position)
}
這里的錯誤是Type mismatch Required: Nothing Found: RecyclerView.ViewHolder。
那么處理這個問題的正確方法是什么?
編輯:只是想清楚其他配接器也將使用此包裝器,因此包裝器必須是通用的。
編輯:我應該提到這一點,有一個類似的包裝器可以正常作業,但它是在 Java 中,該包裝器的類定義是:
public final class MyRecyclerAdapterWrapper extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
public MyRecyclerAdapterWrapper(@NonNull Activity activity,
@NonNull RecyclerView.Adapter originalAdapter){
編輯:根據@muetzenflo 的回答,我能夠讓它大部分作業,但在某些方法上仍然存在問題。
我現在有這個:
class MyRecyclerAdapterWrapper<T : RecyclerView.ViewHolder>(activity: Activity, val originalAdapter: RecyclerView.Adapter<T>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
和
class MyCustomAdapter(): RecyclerView.Adapter<MyCustomAdapter.MyViewHolder>(){
class MyViewHolder(v: View): RecyclerView.ViewHolder(v) {
}
這有效:
val myRecyclerAdapterWrapper = MyRecyclerAdapterWrapper(this, MyCustomAdapter())
但這不會:
genericMethod(myRecyclerAdapterWrapper)
private fun genericMethod(myRecyclerAdapterWrapper: MyRecyclerAdapterWrapper<RecyclerView.ViewHolder>) {
}
錯誤是:
Type mismatch: inferred type is MainActivity.MyRecyclerAdapterWrapper<MainActivity.MyCustomAdapter.MyViewHolder> but MainActivity.MyRecyclerAdapterWrapper<RecyclerView.ViewHolder> was expected
編輯:認為我想出了如何制作通用方法:
private fun <T> genericMethod(myRecyclerAdapterWrapper: MyRecyclerAdapterWrapper<T> ) where T : RecyclerView.ViewHolder {
}
所以最后這就是我的課程結束的方式,它全部編譯并運行:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val myRecyclerAdapterWrapper = MyRecyclerAdapterWrapper(this, MyCustomAdapter())
genericMethod(myRecyclerAdapterWrapper)
}
private fun <T> genericMethod(myRecyclerAdapterWrapper: MyRecyclerAdapterWrapper<T> ) where T : RecyclerView.ViewHolder {
}
class MyRecyclerAdapterWrapper<T : RecyclerView.ViewHolder>(activity: Activity, val originalAdapter: RecyclerView.Adapter<T>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return originalAdapter.onCreateViewHolder(parent,viewType)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
originalAdapter.onBindViewHolder(holder as T,position)
}
override fun getItemCount(): Int {
return originalAdapter.itemCount
}
}
class MyCustomAdapter(): RecyclerView.Adapter<MyCustomAdapter.MyViewHolder>(){
class MyViewHolder(v: View): RecyclerView.ViewHolder(v) {
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
TODO("Not yet implemented")
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
TODO("Not yet implemented")
}
}
}
uj5u.com熱心網友回復:
我在所有專案中都使用了 2 個類,以便在 RecyclerView 專案中普遍使用資料系結:
用法
import androidx.recyclerview.widget.DiffUtil
import de.bvb09.android.R
import de.bvb09.android.data.model.news.NewsComponent
import de.bvb09.android.recyclerview.DataBindingAdapter
import de.bvb09.android.recyclerview.DataBindingViewHolder
/**
* This adapter is responsible for the optional horizontal image gallery
*/
class ZoomImageAdapter : DataBindingAdapter<String>(DiffCallback) {
override fun getItemViewType(position: Int): Int {
return R.layout.item_zoom_image
}
/**
* The DiffCallback is used by the [DataBindingAdapter] to check which items are
* completely new and which just changed its content. When defining the Boolean checks, be
* as precise as possible to avoid strange behaviour of the RecyclerView items.
*/
object DiffCallback : DiffUtil.ItemCallback<String>() {
override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
return oldItem == newItem
}
}
}
串列配接器
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
/**
* This generic Adapter can be used to use any data class T as data provider for recyclerView list items.
* To send a list of items to this adapter, use the submitList(newList) method. The DiffCallback is then called to
* detect which items are completely new or have changed content. Animations are created accordingly and automatically.
*/
abstract class DataBindingAdapter<T>(diffCallback: DiffUtil.ItemCallback<T>) : ListAdapter<T, DataBindingViewHolder<T>>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBindingViewHolder<T> {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = DataBindingUtil.inflate<ViewDataBinding>(layoutInflater, viewType, parent, false)
return DataBindingViewHolder(binding)
}
override fun onBindViewHolder(holder: DataBindingViewHolder<T>, position: Int) {
val item = getItem(position)
holder.bind(item)
}
}
視圖持有者
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import your.package.name.BR
/**
* This ViewHolder is an addition to the [DataBindingAdapter]. From this, it receives a ViewDataBinding which
* allows us to connect the data class T with the data-bindings defined in the item layout.
*/
class DataBindingViewHolder<T>(private val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
var item: T? = null
private set
fun rebind() {
binding.invalidateAll()
binding.executePendingBindings()
}
fun bind(item: T) {
this.item = item
binding.setVariable(BR.item, item)
binding.executePendingBindings()
}
}
uj5u.com熱心網友回復:
引數需要Nothing,因為您宣告out了泛型引數
嘗試更改RecyclerView.ViewHolder為MyOriginalAdapter.MyViewHolder
class MyRecyclerAdapterWrapper(activity: Activity,val originalAdapter: RecyclerView.Adapter<MyOriginalAdapter.MyViewHolder>) : RecyclerView.Adapter<MyOriginalAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyOriginalAdapter.MyViewHolder {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: MyOriginalAdapter.MyViewHolder, position: Int) {
originalAdapter.onBindViewHolder(holder, position)
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
}
}
uj5u.com熱心網友回復:
如果我了解您要做什么,這應該可以解決您的問題。
您可以對 the和 for theRecyclerViewWrapper使用泛型型別AdapterViewHolder
class RecyclerViewWrapper<VH : RecyclerView.ViewHolder, A : RecyclerView.Adapter<VH>>(
activity: Activity,
val originalAdapter: A
) : RecyclerView.Adapter<VH>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: VH, position: Int) {
TODO("Not yet implemented")
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
}
}
你OriginalAdapter可以是你想要的任何配接器
class OriginalAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
TODO("Not yet implemented")
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
}
}
然后要使用它,您可以這樣啟動它
fun example(activity: Activity) {
val wrapper = RecyclerViewWrapper(activity, OriginalAdapter())
}
我認為這將能夠幫助您(只要我理解正確),您可能需要進行細微的更改以滿足您的需求,但沒有任何破壞
uj5u.com熱心網友回復:
您可以使用下面的回收器視圖配接器的包裝類,
public class WrapperRecyclerAdapter extends RecyclerView.Adapter {
private final RecyclerView.Adapter mAdapter;
public WrapperRecyclerAdapter(RecyclerView.Adapter adapter) {
super.setHasStableIds(adapter.hasStableIds());
mAdapter = adapter;
mAdapter.registerAdapterDataObserver(new ForwardingDataSetObserver());
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return mAdapter.onCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
mAdapter.onBindViewHolder(holder, position);
}
@Override
public int getItemViewType(int position) {
return mAdapter.getItemViewType(position);
}
@Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
mAdapter.onViewRecycled(holder);
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
mAdapter.onViewAttachedToWindow(holder);
}
@Override
public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
mAdapter.onViewDetachedFromWindow(holder);
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
mAdapter.onAttachedToRecyclerView(recyclerView);
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
mAdapter.onDetachedFromRecyclerView(recyclerView);
}
@Override
public long getItemId(int position) {
return mAdapter.getItemId(position);
}
@Override
public int getItemCount() {
return mAdapter.getItemCount();
}
private class ForwardingDataSetObserver extends RecyclerView.AdapterDataObserver {
@Override public void onChanged() {
notifyDataSetChanged();
}
@Override public void onItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount);
}
@Override public void onItemRangeInserted(int positionStart, int itemCount) {
notifyItemRangeInserted(positionStart, itemCount);
}
@Override public void onItemRangeRemoved(int positionStart, int itemCount) {
notifyItemRangeRemoved(positionStart, itemCount);
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
notifyDataSetChanged(); //TODO
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/426109.html
