Android 在RecyclerView+;FastAdapter,在单击项目时

Android 在RecyclerView+;FastAdapter,在单击项目时,android,android-layout,animation,android-recyclerview,fastadapter,Android,Android Layout,Animation,Android Recyclerview,Fastadapter,在使用FastAdapter和ConstraintLayout的应用程序中,我会显示已完成游戏的列表(请原谅屏幕截图中的非英语字符): 当应用程序用户单击列表中的某个项目(项目中的任何位置)时,我希望显示一个带有方形游戏板的图像视图,并将正图像视图更改为负图像视图: 为此,我已经准备了一种方法: private void toggleDetails() { if (mBoard.getVisibility() == View.GONE) { mBoard.setVis

在使用FastAdapter和ConstraintLayout的应用程序中,我会显示已完成游戏的列表(请原谅屏幕截图中的非英语字符):

当应用程序用户单击列表中的某个项目(项目中的任何位置)时,我希望显示一个带有方形游戏板的图像视图,并将正图像视图更改为负图像视图:

为此,我已经准备了一种方法:

private void toggleDetails() {
    if (mBoard.getVisibility() == View.GONE) {
        mBoard.setVisibility(View.VISIBLE);
        mDetails.setImageResource(R.drawable.minus_circle_gray);
    } else {
        mBoard.setVisibility(View.GONE);
        mDetails.setImageResource(R.drawable.plus_circle_gray);
    }
}
然而,我的问题是,我不确定在哪里调用该方法

我应该向fast adapter对象添加一个单击侦听器,还是应该将其添加到我的视图持有者

另外,当看这个例子时,我注意到有一些动画,我想知道如何动画我的mBoard图像视图的披露

以下是我当前的源代码:

public class FinishedGameItem extends AbstractItem<FinishedGameItem, FinishedGameItem.ViewHolder> {
    private final static String WON = "won";
    private final static String LOST = "lost";

    public long stamp;
    public int gid;
    public int score1;
    public int score2;
    public int elo1;
    public int elo2;
    public String state1;
    public String finished;
    public String given1;
    public String given2;
    public String photo1;
    public String photo2;

    @Override
    public int getType() {
        return R.id.finished_game_item_id;
    }

    @Override
    public int getLayoutRes() {
        return R.layout.item_finished_game;
    }

    @NonNull
    @Override
    public ViewHolder getViewHolder(@NonNull View v) {
        return new ViewHolder(v);
    }

    protected static class ViewHolder extends FastAdapter.ViewHolder<FinishedGameItem> {
        private ImageView mDetails;
        private TextView mGid;
        private TextView mFinished;
        private TextView mScore1;
        private TextView mScore2;
        private TextView mGiven1;
        private TextView mGiven2;
        private TextView mElo1;
        private TextView mElo2;
        private ImageView mPhoto1;
        private ImageView mPhoto2;
        private ImageView mBoard;

        public ViewHolder(View view) {
            super(view);
            mDetails = view.findViewById(R.id.details);
            mGid = view.findViewById(R.id.gid);
            mFinished = view.findViewById(R.id.finished);
            mScore1 = view.findViewById(R.id.score1);
            mScore2 = view.findViewById(R.id.score2);
            mGiven1 = view.findViewById(R.id.given1);
            mGiven2 = view.findViewById(R.id.given2);
            mElo1 = view.findViewById(R.id.elo1);
            mElo2 = view.findViewById(R.id.elo2);
            mPhoto1 = view.findViewById(R.id.photo1);
            mPhoto2 = view.findViewById(R.id.photo2);
            mBoard = view.findViewById(R.id.board);
        }

        @Override
        public void bindView(@NonNull FinishedGameItem item, @NonNull List<Object> payloads) {
            Context ctx = mDetails.getContext();
            Resources res = mDetails.getResources();

            String result = (WON.equals(item.state1) ? "Victory" : (LOST.equals(item.state1) ? "Loss" : "Draw"));

            mDetails.setImageResource(R.drawable.plus_circle_gray);
            mBoard.setVisibility(View.GONE);

            mGid.setText(r.getString(R.string.str_game, item.gid));
            mFinished.setText(result + " / " + item.finished);
            mScore1.setText(res.getString(R.string.str_score, item.score1));
            mScore2.setText(res.getString(R.string.str_score, item.score2));
            mGiven1.setText(item.given1);
            mGiven2.setText(item.given2);
            mElo1.setText(String.valueOf(item.elo1));
            mElo2.setText(String.valueOf(item.elo2));

            if (URLUtil.isHttpsUrl(item.photo1)) {
                Picasso.with(ctx))
                        .load(item.photo1)
                        .placeholder(R.drawable.account_gray)
                        .into(mPhoto1);
            }

            if (URLUtil.isHttpsUrl(item.photo2)) {
                Picasso.with(ctx)
                        .load(item.photo2)
                        .placeholder(R.drawable.account_gray)
                        .into(mPhoto2);
            }

            Picasso.with(ctx)
                    .load("http://slova.de/words/board2.php?gid=" + item.gid)
                    .placeholder(R.drawable.checkerboard_gray)
                    .into(mBoard);
        }

        @Override
        public void unbindView(@NonNull FinishedGameItem item) {
            Context ctx = mDetails.getContext();

            Picasso.with(ctx).cancelRequest(mPhoto1);
            Picasso.with(ctx).cancelRequest(mPhoto2);
            Picasso.with(ctx).cancelRequest(mBoard);

            mDetails.setImageDrawable(null);
            mGid.setText(null);
            mFinished.setText(null);
            mScore1.setText(null);
            mScore2.setText(null);
            mGiven1.setText(null);
            mGiven2.setText(null);
            mElo1.setText(null);
            mElo2.setText(null);
            mPhoto1.setImageDrawable(null);
            mPhoto2.setImageDrawable(null);
            mBoard.setImageDrawable(null);
        }

        // WHERE TO CALL THIS METHOD AND HOW TO ANIMATE?

        private void toggleDetails() {
            if (mBoard.getVisibility() == View.GONE) {
                mBoard.setVisibility(View.VISIBLE);
                mDetails.setImageResource(R.drawable.minus_circle_gray);
            } else {
                mBoard.setVisibility(View.GONE);
                mDetails.setImageResource(R.drawable.plus_circle_gray);
            }
        }
    }
}
mFastAdapter.withSelectable(true);
mFastAdapter.withOnClickListener(new OnClickListener<FinishedGameItem>() {
    @Override
    public boolean onClick(View v, @NonNull IAdapter<FinishedGameItem> adapter, @NonNull FinishedGameItem item, int position) {
        item.details = !item.details;

        // THIS METHOD IS CALLED IN DEBUGGER, BUT VIEWS ARE NOT UPDATED

        return true;
    }
});
这里是更改后的FinishedGameItem模型:

public class FinishedGameItem extends AbstractItem<FinishedGameItem, FinishedGameItem.ViewHolder> {
    private final static String WON = "won";
    private final static String LOST = "lost";

    public boolean details; // TRIED TO ADD THIS BOOLEAN
    public long stamp;
    public int gid;
    public int score1;
    public int score2;
    public int elo1;
    public int elo2;
    public String state1;
    public String finished;
    public String given1;
    public String given2;
    public String photo1;
    public String photo2;

    @Override
    public int getType() {
        return R.id.finished_game_item_id;
    }

    @Override
    public int getLayoutRes() {
        return R.layout.item_finished_game;
    }

    @NonNull
    @Override
    public ViewHolder getViewHolder(@NonNull View v) {
        return new ViewHolder(v);
    }

    protected static class ViewHolder extends FastAdapter.ViewHolder<FinishedGameItem> {
        private ImageView mDetails;
        private TextView mGid;
        private TextView mFinished;
        private TextView mScore1;
        private TextView mScore2;
        private TextView mGiven1;
        private TextView mGiven2;
        private TextView mElo1;
        private TextView mElo2;
        private ImageView mPhoto1;
        private ImageView mPhoto2;
        private ImageView mBoard;

        public ViewHolder(View view) {
            super(view);
            mDetails = view.findViewById(R.id.details);
            mGid = view.findViewById(R.id.gid);
            mFinished = view.findViewById(R.id.finished);
            mScore1 = view.findViewById(R.id.score1);
            mScore2 = view.findViewById(R.id.score2);
            mGiven1 = view.findViewById(R.id.given1);
            mGiven2 = view.findViewById(R.id.given2);
            mElo1 = view.findViewById(R.id.elo1);
            mElo2 = view.findViewById(R.id.elo2);
            mPhoto1 = view.findViewById(R.id.photo1);
            mPhoto2 = view.findViewById(R.id.photo2);
            mBoard = view.findViewById(R.id.board);
        }

        @Override
        public void bindView(@NonNull FinishedGameItem item, @NonNull List<Object> payloads) {
            Context ctx = mDetails.getContext();
            Resources res = mDetails.getResources();

            String result = (WON.equals(item.state1) ? "Victory" : (LOST.equals(item.state1) ? "Loss" : "Draw"));

            mDetails.setImageResource(item.details ? R.drawable.minus_circle_gray : R.drawable.plus_circle_gray);
            mBoard.setVisibility(item.details ? View.VISIBLE : View.GONE);

            mGid.setText(res.getString(R.string.str_game, item.gid));
            mFinished.setText(result + " / " + item.finished);
            mScore1.setText(res.getString(R.string.str_score, item.score1));
            mScore2.setText(res.getString(R.string.str_score, item.score2));
            mGiven1.setText(item.given1);
            mGiven2.setText(item.given2);
            mElo1.setText(String.valueOf(item.elo1));
            mElo2.setText(String.valueOf(item.elo2));

            if (URLUtil.isHttpsUrl(item.photo1)) {
                Picasso.with(ctx)
                        .load(item.photo1)
                        .placeholder(R.drawable.account_gray)
                        .into(mPhoto1);
            }

            if (URLUtil.isHttpsUrl(item.photo2)) {
                Picasso.with(ctx)
                        .load(item.photo2)
                        .placeholder(R.drawable.account_gray)
                        .into(mPhoto2);
            }

            if (item.details) {
                Picasso.with(ctx)
                        .load("http://slova.de/words/board2.php?gid=" + item.gid)
                        .placeholder(R.drawable.checkerboard_gray)
                        .into(mBoard);
            }
        }

        @Override
        public void unbindView(@NonNull FinishedGameItem item) {
            Context ctx = mDetails.getContext();

            Picasso.with(ctx).cancelRequest(mPhoto1);
            Picasso.with(ctx).cancelRequest(mPhoto2);
            Picasso.with(ctx).cancelRequest(mBoard);

            mDetails.setImageDrawable(null);
            mGid.setText(null);
            mFinished.setText(null);
            mScore1.setText(null);
            mScore2.setText(null);
            mGiven1.setText(null);
            mGiven2.setText(null);
            mElo1.setText(null);
            mElo2.setText(null);
            mPhoto1.setImageDrawable(null);
            mPhoto2.setImageDrawable(null);
            mBoard.setImageDrawable(null);
        }
    }
}
公共类FinishedGameItem扩展了AbstractItem{
私有最终静态字符串WON=“WON”;
私有最终静态字符串LOST=“LOST”;
public boolean details;//尝试添加此布尔值
公众长邮票;
公共信息gid;
公共关系科1;
公共关系2;
公共国际1;
公共国际2;
公共字符串状态1;
公共字符串已完成;
公共字符串1;
公共字符串2;
公共字符串1;
公共字符串2;
@凌驾
公共int getType(){
返回R.id.finished\u game\u item\u id;
}
@凌驾
公共int getLayoutRes(){
返回R.layout.item\u已完成\u游戏;
}
@非空
@凌驾
public ViewHolder getViewHolder(@NonNull View v){
返回新的视图持有者(v);
}
受保护的静态类ViewHolder扩展了FastAdapter.ViewHolder{
私有ImageView mDetails;
私有文本视图mGid;
私有文本视图已完成;
私有文本视图mScore1;
私有文本视图mScore2;
私有文本视图mGiven1;
私有文本视图mGiven2;
私有文本视图mElo1;
私有文本视图mElo2;
私有ImageView mPhoto1;
私有ImageView mPhoto2;
私人影象阅览室;
公共视图持有者(视图){
超级(视图);
mDetails=view.findviewbyd(R.id.details);
mGid=view.findviewbyd(R.id.gid);
mFinished=view.findviewbyd(R.id.finished);
mScore1=view.findViewById(R.id.score1);
mScore2=view.findviewbyd(R.id.score2);
mGiven1=view.findviewbyd(R.id.given1);
mGiven2=view.findViewById(R.id.given2);
mElo1=view.findViewById(R.id.elo1);
mElo2=视图.findViewById(R.id.elo2);
mPhoto1=view.findviewbyd(R.id.photo1);
mPhoto2=view.findviewbyd(R.id.photo2);
mBoard=view.findViewById(R.id.board);
}
@凌驾
public void bindView(@NonNull FinishedGameItem项,@NonNull列表有效负载){
Context ctx=mDetails.getContext();
Resources res=mDetails.getResources();
字符串结果=(赢了.equals(item.state1)?“胜利”:(输了.equals(item.state1)?“输了”:“平局”);
mDetails.setImageResource(item.details?R.drawable.减号圆圈\灰色:R.drawable.plus圆圈\灰色);
mBoard.setVisibility(item.details?View.VISIBLE:View.GONE);
mGid.setText(res.getString(R.string.str_game,item.gid));
mFinished.setText(结果+“/”+项.finished);
mScore1.setText(res.getString(R.string.str_score,item.score1));
mScore2.setText(res.getString(R.string.str_score,item.score2));
mGiven1.SETEXT(项目1);
mGiven2.SETEXT(项目2);
mElo1.setText(String.valueOf(item.elo1));
mElo2.setText(String.valueOf(item.elo2));
if(URLUtil.isHttpsUrl(项目1)){
毕加索(ctx)
.装载(项目1)
.占位符(R.可提取.帐户\U灰色)
.into(mPhoto1);
}
if(URLUtil.isHttpsUrl(项目2)){
毕加索(ctx)
.装载(项目2)
.占位符(R.可提取.帐户\U灰色)
.into(mPhoto2);
}
若有(项目详情){
毕加索(ctx)
.加载(“http://slova.de/words/board2.php?gid=“+item.gid)
.占位符(R.可绘制.棋盘格\ U灰色)
.进入(姆博德);
}
}
@凌驾
public void unbindView(@NonNull FinishedGameItem){
Context ctx=mDetails.getContext();
毕加索.with(ctx).cancelRequest(mPhoto1);
毕加索.with(ctx).cancelRequest(mPhoto2);
毕加索.with(ctx).cancelRequest(mBoard);
mDetails.setImageDrawable(空);
mGid.setText(空);
mFinished.setText(空);
mScore1.setText(空);
mScore2.setText(空);
mGiven1.setText(空);
mGiven2.setText(空);
mElo1.setText(null);
mElo2.setText(空);
mPhoto1.setImageDrawable(空);
mPhoto2.setImageDrawable(空);
mBoard.setImageDrawable(空);
}
}
}
该应用程序工作正常,但不稳定:


根据您的代码判断,您可能忘记实际告诉适配器您的支持型号(
FinishedGameItem
)已更改。调用notifyItemChanged(position)可能会有所帮助

mFastAdapter.withSelectable(true);
mFastAdapter.withOnClickListener(new OnClickListener<FinishedGameItem>() {
    @Override
    public boolean onClick(View v, @NonNull IAdapter<FinishedGameItem> adapter, @NonNull FinishedGameItem item, int position) {
        item.details = !item.details;

        mFastAdapter.notifyItemChanged(position);

        return true;
    }
});
mfasAdapter.with selectable(true);
withOnClickListener(新的OnClickListener(){
@凌驾
公共布尔onClick(视图v、@NonNull IAdapter适配器、@NonNull FinishedGameItem项、int位置){
item.details=!item.details;
mFastAdapter.notifyItemChanged(假定