java - 尝试在 RecyclerView 中添加新元素时,某些项目重复
问题描述
我创建了一个游戏,用户需要在回收站视图中输入玩家的姓名才能开始游戏。
我的问题是,当我尝试添加新玩家时,每 8 或 9 名玩家输入的名字就会重复。
我尝试在网上搜索原因,但未能找到解决方案,并且真的看不出问题出在哪里。
此外,当我修改重复的名称时,它还更改了回收器视图中该名称的每个实例。
该活动运行良好,当游戏开始时,输入的每个名称都在游戏中,没有重复。
编辑:我添加了 holder.playerName.getText().clear(); 在适配器类的 onBindViewHolder 中,纠正了重复问题,但创建了另一个问题:我现在有没有提示的空 EditTexts(EditText 应该提示玩家编号)
编辑2:将 holder.playerName.getText().clear() 行放在 onBindViewHolder 方法中的 holder.playerName.setHint(players.get(position).getName()) 行下就可以了!谢谢!
这是活动的代码:
public class PlayersNameScreen extends AppCompatActivity {
public PlayerMenu playerMenu; // A PlayerMenu used to populate the screen when started
public static PlayerMenu playerMenu1; // A static PlayerMenu to store all the players entered on this screen and access it on the next
private RecyclerView listOfPlayers; // The recycler view where the players can see, add and enter other players
private ListOfPlayersAdapter listOfPlayersAdapter; // The adapter for the recycler view
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeScreen();
}
/**
* Sets the contents of the screen
*/
private void initializeScreen() {
setContentView(R.layout.activity_players_name_screen);
listOfPlayers = findViewById(R.id.playerNames);
// The button used to add a player
FloatingActionButton addPlayer = findViewById(R.id.addPlayer);
// Start the game with the new players entered, filtering the menu as well
// The button to start the game
Button startGame = findViewById(R.id.Booze);
startGame.setOnClickListener(view -> {
playerMenu1 = new PlayerMenu();
playerMenu1.removeAllPlayers();
playerMenu1.addAllPlayers(playerMenu.getPlayers());
playerMenu1.filter();
goToCardScreen();
});
playerMenu = new PlayerMenu();
// Set the default view of the list
setListOfPlayersView(playerMenu.getPlayers());
// Adds a row to the list and a player to the menu, scrolls to the new player entered
addPlayer.setOnClickListener((View view) -> {
playerMenu.addPlayer(playerMenu.size());
listOfPlayersAdapter.notifyItemInserted(playerMenu.size() - 1);
listOfPlayers.smoothScrollToPosition(playerMenu.size() - 1);
});
}
/**
* Creates the list of all the players (the view)
* @param playerz the list of the players
*/
void setListOfPlayersView(ArrayList<Player> playerz) {
listOfPlayersAdapter = new ListOfPlayersAdapter(playerz);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
listOfPlayers.setLayoutManager(layoutManager);
listOfPlayers.setItemAnimator(new DefaultItemAnimator());
listOfPlayers.setAdapter(listOfPlayersAdapter);
}
/**
* Before launching the game, check that the names are correct
*/
private void goToCardScreen() {
Set<String> set = new HashSet<>(playerMenu1.getPlayersNames());
boolean playersNameOK = true;
boolean playersEntered = true;
boolean enoughPlayers = true;
if (set.size() < playerMenu1.getPlayers().size()) {
// Shows a message that the player entered duplicated names
playersNameOK = false;
}
if (set.isEmpty()) {
// Shows a message saying they need to enter players
playersEntered = false;
}
if (set.size() == 1) {
// Shows a message showing that there aren't enough players
enoughPlayers = false;
}
if (playersNameOK && playersEntered && enoughPlayers) {
createWaiver(); --> eventually leads to next activity
}
}
}
这是适配器的代码
public class ListOfPlayersAdapter extends RecyclerView.Adapter<ListOfPlayersAdapter.MyViewHolder>{
private ArrayList<Player> players; // The array to old every player entered
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.player_name_row, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
int x = holder.getLayoutPosition();
// If a real name was entered (names that don't include the string <player>), set the text of the EditText to the name of the player
if (!players.get(x).getName().contains("Player")){
holder.playerName.setText(players.get(x).getName());
}
else {
// Keep hinting the player number (aka Player x)
holder.playerName.setHint(players.get(position).getName());
holder.playerName.getText().clear();
}
}
@Override
public int getItemCount() {
return players.size();
}
ListOfPlayersAdapter(ArrayList<Player> players) {
this.players = players;
}
class MyViewHolder extends RecyclerView.ViewHolder {
private EditText playerName;
MyViewHolder(View itemView) {
super(itemView);
playerName = itemView.findViewById(R.id.playerInput);
playerName.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Player playerBis = new Player(s.toString());
players.set(getAdapterPosition(),playerBis);
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
}
}
这是播放器菜单的代码:
class PlayerMenu {
private ArrayList<Player> players; // List to store every player
PlayerMenu() {
// Creating and adding the players to the menu
players = new ArrayList<>();
Player player1 = new Player("Player 1");
Player player2 = new Player("Player 2");
Player player3 = new Player("Player 3");
players.add(player1);
players.add(player2);
players.add(player3);
}
/**
*
* @param i The position of the player in the list
* @return The name of the player
*/
String getPlayer(int i) {
return players.get(i).getName();
}
/**
* Method to add a player in the menu
*/
void addPlayer(int position){
Player player = new Player("Player" + " " + (players.size() + 1));
players.add(position, player);
}
/**
* Method to add all players from an ArrayList to the players array list
* @param playerz The ArrayList we want to get the players from
*/
void addAllPlayers(ArrayList<Player> playerz) {
players.addAll(playerz);
}
/**
* Method to remove all players from the list
*/
void removeAllPlayers() {
players.clear();
}
/**
* To see the list of players
* @return the list of all the players
*/
ArrayList<Player> getPlayers() {
return players;
}
/**
* Remove from the list of players all those who are nameless (aka Player i)
*/
void filter() {
players.removeIf(player -> player.getName().toLowerCase().contains("player")) || player.getName().isEmpty()));
}
/**
* Size of the list
* @return the size of the list of players
*/
public int size() {
return players.size();
}
}
添加一个名为 Bob 的新玩家,然后向下滚动:Bob 被复制
如果我们一直按“+”按钮,每 6-9 次,输入的名称就会重复
解决方案
尝试在您的 bindviewholder 方法中添加以下代码:
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
int x = holder.getLayoutPosition();
// If a real name was entered (names that don't include the string <player>), set the text of the EditText to the name of the player
if (!players.get(x).getName().contains("Player")){
holder.playerName.setText(players.get(x).getName());
}
else {
holder.playerName.setText("")
// Keep hinting the player number (aka Player x)
holder.playerName.setHint(players.get(position).getName());
}
}
holder.playerName.setText("") 您还需要在 else 条件下添加一些值,因为 recyclerview 会回收项目,因此您会得到重复的项目。
希望这可以帮助!
推荐阅读
- php - 响应中“Access-Control-Allow-Credentials”标头的值为“”,必须为“真”
- pg-promise - node-postgres/pg-promise 中的多用户连接
- firebase - 更新flutter中的变量值
- sql - SQL 帮助读取 XML 列中的值
- awk - 将一个文件中第三列的值与另一个文件中的值进行比较
- unity3d - BeeByte 反混淆
- css - 在表格单元格之间居中放置图像
- .htaccess - 重定向 htacces 除了单词
- spring-boot - Spring boot的嵌入式Tomcat启动后立即关闭
- ruby-on-rails - 导入语句后开玩笑的意外标识符