我创建了一个游戏,用户需要在回收器 View 中输入玩家的姓名才能开始游戏。
我的问题是,当我尝试添加新玩家时,每 8 或 9 个玩家,输入的名字就会重复。
我尝试在网上搜索原因,但没有成功找到解决方案,而且真的看不出问题出在哪里。
此外,当我修改重复的名称时,它还会更改回收器 View 中该名称的每个实例。
该 Activity 运行良好,当游戏开始时,输入的每个名称都在游戏中,没有重复。
编辑:我添加了holder.playerName.getText().clear();在适配器类的 onBindViewHolder 中,它纠正了重复问题,但又创建了另一个问题:我现在有空的 EditText,没有任何提示(其中 EditText 应该提示玩家编号)
编辑2:将holder.playerName.getText().clear()行放在onBindViewHolder方法中的holder.playerName.setHint(players.get(position).getName())行下就可以了! 谢谢!
以下是该 Activity 的代码:
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();
}
}
When the activity screen loads and when we press on the "+" button
Adding a new player called Bob, and scrolling down: Bob is duplicated
If we add a new player John (at the top)...
...and press on the "+" button, John is also duplicated
If we keep pressing the "+" button, every 6-9 times, the names entered are duplicated
If we replace one of the player's name (here John) with another name (Karen)...
... and scroll back up, we can see that some instances of John are replaced with karen
最佳答案
尝试在您的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("") You need to add some value in else condition also, as recyclerview recycles the items and hence you are getting duplicate items.
希望这有帮助!
关于java - 尝试在 RecyclerView 中添加新元素时,某些项目重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57825794/