android - 如何在不替换项目的情况下在一个 Recyclerview 中添加两个自定义行?

标签 android android-recyclerview

如何在不替换项目的情况下在一个 Recyclerview 中添加两个自定义行,它显示两个自定义行但它删除了项目编号 1 我该如何解决?

代码

public class MessagesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    private List<MessagesEntity> messagesEntityList;
    private AppDatabase appDatabase;
    private Typeface typeface;

    public MessagesAdapter(Context context, List<MessagesEntity> messagesEntityList) {
        this.context = context;
        this.messagesEntityList = messagesEntityList;
        appDatabase = Room.databaseBuilder(context, AppDatabase.class, "app_database").allowMainThreadQueries().build();
        typeface = Typeface.createFromAsset(context.getAssets(), "MainFont.ttf");
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == 100) {
            return new ViewHolder1(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_short_description, parent, false));
        } else {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_message, parent, false));
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (getItemViewType(position) == 100) {
            ViewHolder1 viewHolder1 = (ViewHolder1) holder;
            viewHolder1.txtShortDescription.setTypeface(typeface);
            viewHolder1.txtShortDescription.setText(MessagesActivity.description);
        } else {
            ViewHolder viewHolder = (ViewHolder) holder;
            viewHolder.txtMessage.setTypeface(typeface);
            if (position % 2 == 0) {
                viewHolder.linearLayout1.setBackgroundColor(context.getResources().getColor(R.color.m_a_1_row_background_1));
                viewHolder.txtMessage.setTextColor(context.getResources().getColor(R.color.m_a_1_row_category_name_2));
            } else if (position % 2 == 1) {
                viewHolder.linearLayout1.setBackgroundColor(context.getResources().getColor(R.color.m_a_1_row_background_2));
                viewHolder.txtMessage.setTextColor(context.getResources().getColor(R.color.m_a_1_row_category_name_1));
            }
            if (appDatabase.favoriteDao().getMessage(messagesEntityList.get(position).getId()).size() == 0) {
                viewHolder.imgFavorite.setColorFilter(context.getResources().getColor(R.color.white), PorterDuff.Mode.SRC_IN);
            } else {
                viewHolder.imgFavorite.setColorFilter(context.getResources().getColor(R.color.cinnabar), PorterDuff.Mode.SRC_IN);
            }
            viewHolder.txtMessage.setText(messagesEntityList.get(position).getMessage());
        }
    }

    @Override
    public int getItemCount() {
        return messagesEntityList.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return 100;
        } else {
            return super.getItemViewType(position);
        }
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.linear_layout_1)
        LinearLayout linearLayout1;
        @BindView(R.id.txt_message)
        TextView txtMessage;
        @BindView(R.id.img_favorite)
        ImageView imgFavorite;
        @BindView(R.id.img_copy)
        ImageView imgCopy;
        @BindView(R.id.img_share)
        ImageView imgShare;

        ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        @OnClick({R.id.img_share, R.id.img_copy, R.id.img_favorite})
        void onClick(View view) {
            switch (view.getId()) {
                case R.id.img_share:
                    Intent intent = new Intent(Intent.ACTION_SEND);
                    intent.putExtra(Intent.EXTRA_TEXT, messagesEntityList.get(getAdapterPosition()).getMessage());
                    intent.setType("text/plain");
                    context.startActivity(Intent.createChooser(intent, ""));
                    break;
                case R.id.img_copy:
                    ClipboardManager clipboard = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
                    clipboard.setPrimaryClip(ClipData.newPlainText("copied", messagesEntityList.get(getAdapterPosition()).getMessage()));
                    CustomToast.show(context, context.getResources().getString(R.string.copied));
                    break;
                case R.id.img_favorite:
                    if (appDatabase.favoriteDao().getMessage(messagesEntityList.get(getAdapterPosition()).getId()).size() == 0) {
                        FavoriteEntity favoriteEntity = new FavoriteEntity();
                        favoriteEntity.setId(messagesEntityList.get(getAdapterPosition()).getId());
                        favoriteEntity.setMessage(messagesEntityList.get(getAdapterPosition()).getMessage());
                        favoriteEntity.setCategoryName(messagesEntityList.get(getAdapterPosition()).getCategoryName());
                        appDatabase.favoriteDao().addMessage(favoriteEntity);
                        CustomToast.show(context, context.getResources().getString(R.string.added_to_favorite));
                        imgFavorite.setColorFilter(context.getResources().getColor(R.color.cinnabar), PorterDuff.Mode.SRC_IN);
                    } else {
                        appDatabase.favoriteDao().deleteMessage(messagesEntityList.get(getAdapterPosition()).getId());
                        CustomToast.show(context, context.getResources().getString(R.string.removed_from_favorite));
                        imgFavorite.setColorFilter(context.getResources().getColor(R.color.white), PorterDuff.Mode.SRC_IN);
                    }
                    break;
            }
        }

    }

    class ViewHolder1 extends RecyclerView.ViewHolder {

        @BindView(R.id.linear_layout_1)
        LinearLayout linearLayout1;
        @BindView(R.id.txt_short_description)
        TextView txtShortDescription;

        ViewHolder1(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

    }

}

我想先显示 row_short_description 行,然后显示所有项目而不删除任何数据................................................ ..................................................... ..................................................... .

最佳答案

容易的事情是修复索引。您现在有 messagesEntityList.size() + 1 个项目,所以:

@Override
public int getItemCount() {
    return messagesEntityList.size() + 1;
}

但是,您还必须修复 onBindViewHolder 中的索引,但这容易出错。适配器不应该知道所有这些,您应该只向它提供数据,然后它会绑定(bind)到 View 持有者。

更好的解决方案是创建两个类,它们从同一个接口(interface)扩展:

// Base message for the adapter
interface BaseMessage {}


// Message for the adapter
class Message implements BaseMessage {

    private int id;
    private String message;
    private String categoryName;

    Message(int id, String message, String categoryName) {
        this.id = id;
        this.message = message;
        this.categoryName = categoryName;
    }

    public int getId() {
        return id;
    }

    public String getMessage() {
        return message;
    }

    public String getCategoryName() {
        return categoryName;
    }
}


// Message description for the adapter
class MessageDescription implements BaseMessage { }

然后是您的适配器(您需要在需要时将 BaseMessage 从列表转换为 Message):

// BaseMessage: Message, MessageDescription
// Message -- MessageViewHolder
// MessageDescription -- DescriptionViewHolder
public class MessagesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int VIEW_TYPE_MESSAGE = 0;
    private static final int VIEW_TYPE_SHORT_DESCRIPTION = 1;

    private Context context;
    private List<BaseMessage> messages;
    private AppDatabase appDatabase;
    private Typeface typeface;

    public MessagesAdapter(Context context, List<BaseMessage> messages) {
        this.context = context;
        this.messages = messages;
        appDatabase = Room.databaseBuilder(context, AppDatabase.class, "app_database").allowMainThreadQueries().build();
        typeface = Typeface.createFromAsset(context.getAssets(), "MainFont.ttf");
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        if (viewType == VIEW_TYPE_SHORT_DESCRIPTION) {
            return new DescriptionViewHolder(inflater.inflate(R.layout.row_short_description, parent, false));
        } else {
            return new MessageViewHolder(inflater.inflate(R.layout.row_message, parent, false));
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        int viewType = getItemViewType(position);
        if (viewType == VIEW_TYPE_SHORT_DESCRIPTION) {
            DescriptionViewHolder viewHolder1 = (DescriptionViewHolder) holder;
            viewHolder1.txtShortDescription.setTypeface(typeface);
            viewHolder1.txtShortDescription.setText(MessagesActivity.description);
        } else {
            MessageViewHolder viewHolder = (MessageViewHolder) holder;
            Message message = (Message) messages.get(position);
            viewHolder.txtMessage.setTypeface(typeface);
            if (position % 2 == 0) {
                viewHolder.linearLayout1.setBackgroundColor(context.getResources().getColor(R.color.m_a_1_row_background_1));
                viewHolder.txtMessage.setTextColor(context.getResources().getColor(R.color.m_a_1_row_category_name_2));
            } else {
                viewHolder.linearLayout1.setBackgroundColor(context.getResources().getColor(R.color.m_a_1_row_background_2));
                viewHolder.txtMessage.setTextColor(context.getResources().getColor(R.color.m_a_1_row_category_name_1));
            }
            if (appDatabase.favoriteDao().getMessage(message.getId()).size() == 0) {
                viewHolder.imgFavorite.setColorFilter(context.getResources().getColor(R.color.white), PorterDuff.Mode.SRC_IN);
            } else {
                viewHolder.imgFavorite.setColorFilter(context.getResources().getColor(R.color.cinnabar), PorterDuff.Mode.SRC_IN);
            }
            viewHolder.txtMessage.setText(message.getMessage());
        }
    }

    @Override
    public int getItemCount() {
        return messages.size();
    }

    @Override
    public int getItemViewType(int position) {
        BaseMessage base = messages.get(position);
        if (base instanceof MessageDescription) {
            return VIEW_TYPE_SHORT_DESCRIPTION;
        } else {
            return VIEW_TYPE_MESSAGE;
        }
    }

    class MessageViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.linear_layout_1)
        LinearLayout linearLayout1;
        @BindView(R.id.txt_message)
        TextView txtMessage;
        @BindView(R.id.img_favorite)
        ImageView imgFavorite;
        @BindView(R.id.img_copy)
        ImageView imgCopy;
        @BindView(R.id.img_share)
        ImageView imgShare;

        MessageViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        @OnClick({R.id.img_share, R.id.img_copy, R.id.img_favorite})
        void onClick(View view) {
            Message message = (Message) messages.get(getAdapterPosition());
            switch (view.getId()) {
                case R.id.img_share:
                    Intent intent = new Intent(Intent.ACTION_SEND);
                    intent.putExtra(Intent.EXTRA_TEXT, message.getMessage());
                    intent.setType("text/plain");
                    context.startActivity(Intent.createChooser(intent, ""));
                    break;
                case R.id.img_copy:
                    ClipboardManager clipboard = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
                    clipboard.setPrimaryClip(ClipData.newPlainText("copied", message.getMessage()));
                    CustomToast.show(context, context.getResources().getString(R.string.copied));
                    break;
                case R.id.img_favorite:
                    if (appDatabase.favoriteDao().getMessage(message.getId()).size() == 0) {
                        FavoriteEntity favoriteEntity = new FavoriteEntity();
                        favoriteEntity.setId(message.getId());
                        favoriteEntity.setMessage(message.getMessage());
                        favoriteEntity.setCategoryName(message.getCategoryName());
                        appDatabase.favoriteDao().addMessage(favoriteEntity);
                        CustomToast.show(context, context.getResources().getString(R.string.added_to_favorite));
                        imgFavorite.setColorFilter(context.getResources().getColor(R.color.cinnabar), PorterDuff.Mode.SRC_IN);
                    } else {
                        appDatabase.favoriteDao().deleteMessage(message.getId());
                        CustomToast.show(context, context.getResources().getString(R.string.removed_from_favorite));
                        imgFavorite.setColorFilter(context.getResources().getColor(R.color.white), PorterDuff.Mode.SRC_IN);
                    }
                    break;
            }
        }

    }

    class DescriptionViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.linear_layout_1)
        LinearLayout linearLayout1;
        @BindView(R.id.txt_short_description)
        TextView txtShortDescription;

        DescriptionViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

    }

}

然后从你的 Activity 中:

// Create a description object
MessageDescription description = MessageDescription();
List<Message> messages = ... // get your messages from the DB, convert them to Message class
// Combine the description and messages into one list
List<BaseMessage> combinedMessages = new ArrayList<>();
// Put description on the first place
combinedMessages.add(description);
combinedMessages.addAll(messages);
MessagesAdapter adapter = new MessagesAdapter(this, combinedMessages);
recyclerView.adapter = adapter;

关于android - 如何在不替换项目的情况下在一个 Recyclerview 中添加两个自定义行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58640553/

相关文章:

安卓 "adb shell input keyevent KEYCODE_SEARCH"不工作

java - Android Studio仅支持一个settings.gradle吗?

android - 更改 Google Play 上销售的应用程序的 Google Checkout 帐户的货币/所在国家/地区

android - 在 Kotlin 中设置 startActivity() 时类型不匹配

android - RecyclerView onClick 在过滤器适配器上出现错误

android - 如何在 Android 上禁用网页缩放/缩放?

android - widget.newButton 显示在模拟器中但不显示在设备上

android - 单元测试 RecyclerView OnItemTouchListener Robolectric

android - CardView 未显示在 RecyclerView 中

android - 滚动时处理 recyclerview 项目的文件上传进度?