Dan*_*ina 7 performance android android-layout android-recyclerview
我想用的物品,其中最后一个项目是一个按钮,添加了"标准"类型的新项目列表中创建的布局.它应该像Google Keep列表一样,在列表的末尾有一个永久的"添加"项. Google Keep列表示例
我尝试了两种方法来实现它.第一个很简单,但我发现了一个问题.第二个并不那么简单,性能更差.另外,我认为我使用的第二种方式RecyclerView是非预期的方式,我认为我可以找到性能问题.
你会怎么做?
第一种方式
第一个应该是最简单的,即添加相同的布局a,RecyclerView然后ViewGroup包含"添加"项.作为父级,我使用LinearLayout带有"添加"项布局的RecyclerView 和Include标记.这实际上是在一个CoordinatorLayout因为我使用a BottomSheet来选择要添加的新"标准"项目.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBackgroundLight"
android:orientation="vertical">
<!-- Other Views -->
<android.support.v7.widget.RecyclerView
android:id="@+id/mainRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="@layout/itemAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
问题是"添加"项位于下方RecyclerView,并且当它RecyclerView为空时都消失.
第二种方式
然后我尝试了第二种方法,即从中创建"添加"项RecyclerView.Adapter.到目前为止,这样做是有效的,尽管我确信这不是最好的方法.我将粘贴代码,在下面我解释背后的原因.
适配器
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
private final LayoutInflater mInflater;
private BottomSheetBehavior bottomSheetBehavior;
private int count = 0;
private final List<Object> mDataset;
// Standard constructor. I get the mInflater from Context here
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View itemView;
if (count>=mDataset.size()) {
itemView = mInflater.inflate(R.layout.item_add, parent, false);
itemView.setTag("ADD");
}
else{
itemView = mInflater.inflate(R.layout.item_sandard, parent, false);
itemView.setTag(null);
}
count += 1;
return new MyViewHolder(itemView, bottomSheetBehavior);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (position<mDataset.size()) {
final Object object = mDataset.get(position);
holder.bind(object); // I bind it on the ViewHolder
}
}
@Override
public int getItemCount() {
return mDataset.size()+1;
}
}
Run Code Online (Sandbox Code Playgroud)
为此,我创建了一个私有变量mCount,用于计算ViewHolder创建的数量.然后我onCreateViewHolder用if语句启动我的方法,在那里我检查我是否已经创建了mDatasetViewHolder的最后一个"标准"项.根据它,我膨胀"标准"视图或"添加"视图.然后,每次用户添加或删除项目(尚未实现)时,我都必须更新mCount值.我还在视图中添加了一个标签,以便在没有大麻烦的情况下使用它.ViewViewHolder
我必须更改,onBindViewHolder因为如果我正在膨胀"添加"视图,我不想绑定任何东西,因为视图已经定义.
我还必须修改getItemCount方法以返回mDataset的大小加上"添加"视图的1.
最后,我已经被发送BottomSheetBehaviour一路实例的ViewHolder通过Adapter才能够打开BottomSheet与onClick中定义的ViewHolder,我不认为这是非常有效的.
ViewHolder
public class MyViewHolder extends RecyclerView.ViewHolder{
private final TextView mText;
private final ImageButton mButton;
public MyViewHolder(View itemView, final BottomSheetBehavior bottomSheetBehavior) {
super(itemView);
if (itemView.getTag() == "ADD"){
mText = null;
mButton = null;
// I also set the OnClickListener to open the BottomSheet
}
else{
// Set mText and an OnClickListener to the button. I use the Adapter here
}
}
// The bind method goes here
}
Run Code Online (Sandbox Code Playgroud)
在这里我从中获取标签View,并根据它设置不同的监听器.
小智 2
我可能会迟到,但如果您还没有找到任何解决方案,请尝试这种方式..!!
class AddMorePhotosAdapter(
val context: Context,
private val addImageListener: () -> Unit
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val imageList = ArrayList<Bitmap>()
fun addAll(list: ArrayList<Bitmap>) {
imageList.clear()
imageList.addAll(list)
notifyDataSetChanged()
}
inner class MyItemHolder(val binding: ItemSelectedPhotoBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(path: Bitmap, position: Int) {
Glide.with(context)
.asBitmap()
.placeholder(R.mipmap.ic_launcher)
.load(path)
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(
resource: Bitmap,
transition: Transition<in Bitmap>?
) {
binding.tvSelectedImage.apply {
setImageBitmap(resource)
scaleType = ImageView.ScaleType.FIT_XY
}
}
})
}
}
inner class MyFooterHolder(val binding: LayoutMultiplePhotoBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind() {
binding.tvAddImage.setOnClickListener {
addImageListener.invoke()
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val binding: ViewBinding
if (viewType == TYPE_ITEM) {
binding =
ItemSelectedPhotoBinding.inflate(LayoutInflater.from(context), parent, false)
return MyItemHolder(binding)
} else if (viewType == TYPE_FOOTER) {
binding =
LayoutMultiplePhotoBinding.inflate(LayoutInflater.from(context), parent, false)
return MyFooterHolder(binding)
}
throw RuntimeException("There is no type that matches the type $viewType. Make sure you are using view types correctly!")
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemViewType(position)) {
TYPE_ITEM -> (holder as MyItemHolder).bind(imageList[position], position)
TYPE_FOOTER -> (holder as MyFooterHolder).bind()
}
}
override fun getItemCount(): Int = imageList.size + 1
override fun getItemViewType(position: Int): Int {
return if (position == imageList.size) {
TYPE_FOOTER
} else {
TYPE_ITEM
}
}
companion object {
private const val TYPE_ITEM = 1
private const val TYPE_FOOTER = 0
}
}
Run Code Online (Sandbox Code Playgroud)
-- 我使用 TYPE_TIME 来显示带有 recyclerview 的列表,并使用 TYPE_FOOTER 来显示“添加”图像。两种布局的充气方式都会有所不同。
检查此图像以供参考。最初它只是“添加”图像
| 归档时间: |
|
| 查看次数: |
2979 次 |
| 最近记录: |