单击项目后,在 RecyclerView + FastAdapter 中显示更多详细信息
Showing more details in RecyclerView + FastAdapter, when the item has been clicked
在使用 FastAdapter 和 ConstraintLayout 的应用程序中,我显示了已完成游戏的列表(请原谅屏幕截图中的 non-english 个字符):
当应用程序用户单击列表中的项目(项目中的任何位置)时,我想显示带有方形游戏板的图像视图,并将加号图像视图更改为减号:
为此我已经准备了一个方法:
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);
}
}
但是我的问题是我不确定在哪里调用该方法。
我应该将点击侦听器添加到快速适配器对象还是应该将其添加到我的视图持有者?
此外,在查看 ExpandableSampleActivity 示例时,我注意到有一些动画,想知道如何为我公开的 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);
}
}
}
}
我也在 Github issue 713
中问过我的问题
更新:
我已经尝试在我的模型中添加一个布尔值 details
并在 bindView
方法中使用它(true 表示显示 mBoard
),但应用程序现在表现不稳定,错误显示详细信息,但不会在单击后立即显示 -
这里是新的片段源代码:
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
) 已更改。致电 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;
}
});
在使用 FastAdapter 和 ConstraintLayout 的应用程序中,我显示了已完成游戏的列表(请原谅屏幕截图中的 non-english 个字符):
当应用程序用户单击列表中的项目(项目中的任何位置)时,我想显示带有方形游戏板的图像视图,并将加号图像视图更改为减号:
为此我已经准备了一个方法:
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);
}
}
但是我的问题是我不确定在哪里调用该方法。
我应该将点击侦听器添加到快速适配器对象还是应该将其添加到我的视图持有者?
此外,在查看 ExpandableSampleActivity 示例时,我注意到有一些动画,想知道如何为我公开的 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);
}
}
}
}
我也在 Github issue 713
中问过我的问题更新:
我已经尝试在我的模型中添加一个布尔值 details
并在 bindView
方法中使用它(true 表示显示 mBoard
),但应用程序现在表现不稳定,错误显示详细信息,但不会在单击后立即显示 -
这里是新的片段源代码:
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
) 已更改。致电 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;
}
});