带有自定义适配器的列表视图 - 每个其他项目元素都是重复的
listview with a custom adapter - every other item element are duplicates
我的列表视图及其自定义适配器遇到了一些奇怪的问题(我认为)。
问题是我的列表视图中的每个项目都有一些不同的视图元素,例如 EditText 字段等。
每当我在列表视图中有超过 2 个项目时,这些元素的条目现在在所有其他项目中。
我举个例子:
- 我正在向列表视图中添加 8 个项目。
- 我在第一个文本字段中输入一个值
- 现在在文本字段中重复相同的值:3、5 和 7
- 如果我在第二个项目的文本字段中输入一个值,该值将在项目编号的文本字段中重复:4、6 和 8
希望你现在能看到问题。
这里是这个问题的一些相关代码:
首先,我的自定义适配器 (CreateProgramAdapter) 的代码:
public class CreateProgramAdapter extends BaseAdapter {
private LayoutInflater inflater;
private ArrayList<TrainingPass> trainingPasses;
private List<TrainingPass> items;
private int layoutResourceId;
private Context context;
public CreateProgramAdapter(Context context, List<TrainingPass> items) {
this.context = context;
this.items = items;
this.inflater = LayoutInflater.from(this.context);
}
@Override
public int getCount() {
return items.size();
}
@Override
public TrainingPass getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
TrainingPassHolder holder;
if(convertView == null) {
view = inflater.inflate(R.layout.adapter_createprogram_trainingpasses_item, parent, false);
holder = new TrainingPassHolder();
view.setTag(holder);
} else {
view = convertView;
holder = (TrainingPassHolder)view.getTag();
}
holder.trainingPass = this.getItem(position);
holder.trainingPass.trainingPassID = position + 1;
holder.trainingPassContainer = (RelativeLayout) view.findViewById(R.id.trainingPassContainer);
holder.trainingPassHeadlineShowHide = (TextView) view.findViewById(R.id.trainingpass_headline);
holder.noExercisesYet = (TextView) view.findViewById(R.id.txt_no_exercises_yet);
holder.exerciseSearchField = (EditText) view.findViewById(R.id.trainingpass_exercise_searchfield);
holder.trainingPassSetsListView = (ListView) view.findViewById(R.id.trainingpass_sets_listview);
holder.exercisesListView = (ListView) view.findViewById(R.id.exercises_listview);
holder.addSetButton = (Button) view.findViewById(R.id.add_set_button);
holder.addExerciseButton = (Button) view.findViewById(R.id.add_exercise_button);
holder.deleteTrainingpass = (Button) view.findViewById(R.id.delete_trainingpass_button);
holder.doneTrainingpass = (Button) view.findViewById(R.id.done_trainingpass_button);
setupItems(holder);
return view;
}
private void setupItems(TrainingPassHolder trainingPassHolder) {
final TrainingPassHolder holder = trainingPassHolder;
int trainingPassID = trainingPassHolder.trainingPass.trainingPassID;
TextView showHide = holder.trainingPassHeadlineShowHide;
Button addSet = holder.addSetButton;
Button deleteTrainingPass = holder.deleteTrainingpass;
final EditText exerciseNameField = holder.exerciseSearchField;
// Set title of the trainingpass
showHide.setText("Trainingpass " + trainingPassID);
// Set name of exercise
if (trainingPassHolder.trainingPass.tempExerciseName != null) {
System.out.println(holder.trainingPass.tempExerciseName);
exerciseNameField.setText(holder.trainingPass.tempExerciseName);
} else {
exerciseNameField.setText("");
}
// Add 1 default set to exercise
if (holder.sets.size() == 0) {
holder.sets.add(1);
}
/*
Set adapter for sets of the listview for the trainingpass
*/
final TrainingPassSetsAdapter createProgramAdapter = new TrainingPassSetsAdapter(context, holder.sets);
holder.trainingPassSetsListView.setAdapter(createProgramAdapter);
exerciseNameField.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
holder.trainingPass.tempExerciseName = exerciseNameField.getText().toString();
return false;
}
});
/*
Show / hide the trainingpass
*/
showHide.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.trainingPass.visible) {
holder.trainingPass.visible = false;
holder.trainingPassContainer.setVisibility(View.GONE);
} else {
holder.trainingPass.visible = true;
holder.trainingPassContainer.setVisibility(View.VISIBLE);
}
}
});
/*
Add set to the listview
*/
addSet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.sets.add(1);
createProgramAdapter.notifyDataSetChanged();
}
});
/*
Delete training pass
*/
deleteTrainingPass.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
items.remove(holder.trainingPass);
notifyDataSetChanged();
}
});
}
private static class TrainingPassHolder {
ArrayList<Integer> sets = new ArrayList<Integer>();
TrainingPass trainingPass;
RelativeLayout trainingPassContainer;
TextView trainingPassHeadlineShowHide;
TextView noExercisesYet;
EditText exerciseSearchField;
ListView trainingPassSetsListView;
ListView exercisesListView;
Button addSetButton;
Button addExerciseButton;
Button deleteTrainingpass;
Button doneTrainingpass;
}
}
这里是 class TrainingPass 的代码:
public class TrainingPass {
public String trainingPassName;
public ArrayList<Exercise> exercises;
public int trainingPassID;
public boolean visible = false;
public String tempExerciseName;
public TrainingPass() {
exercises = new ArrayList<Exercise>();
}
public void addExercise(Exercise exercise ) {
exercises.add(exercise);
}
}
activity class CreateProgramActivity 的代码:
public class CreateProgramActivity extends CustomActivity {
private ArrayList<TrainingPass> trainingPasses;
private CreateProgramAdapter createProgramAdapter;
private ListView trainingPassesListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_program);
trainingPasses = new ArrayList<TrainingPass>();
trainingPassesListView = (ListView)findViewById(R.id.listView_trainingpasses);
createProgramAdapter = new CreateProgramAdapter(CreateProgramActivity.this, trainingPasses);
trainingPassesListView.setAdapter(createProgramAdapter);
}
public void addTrainingPass(View v) {
TrainingPass trainingPass = new TrainingPass();
trainingPasses.add(trainingPass);
createProgramAdapter.notifyDataSetChanged();
}
public void addTrainingPassHelp(View v) {
Toast.makeText(this, "Add training pass HELP!", Toast.LENGTH_SHORT).show();
}
public void createProgram(View v) {
Toast.makeText(this, "Create program", Toast.LENGTH_SHORT).show();
}
}
这是 CreateProgramActivity 的 xml 布局,包含父列表视图:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mobileplatformexam.activities.CreateProgramActivity"
android:id="@+id/relativeLayoutCreateProgram">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add training pass"
android:id="@+id/btn_add_trainingpass"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@+id/btn_add_trainingpass_help"
android:layout_toStartOf="@+id/btn_add_trainingpass_help"
android:onClick="addTrainingPass"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="\?"
android:id="@+id/btn_add_trainingpass_help"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:onClick="addTrainingPassHelp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create program"
android:id="@+id/btn_create_program"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/btn_add_trainingpass_help"
android:layout_alignEnd="@+id/btn_add_trainingpass_help"
android:onClick="createProgram"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView_trainingpasses"
android:layout_above="@+id/btn_create_program"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/btn_add_trainingpass" />
</RelativeLayout>
最后,这是我的 xml 父列表视图项目的布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/trainingpass_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="false"
android:layout_alignParentTop="true"
android:text="Trainingpass"
android:textSize="16dp"
android:textColor="@android:color/white"
android:background="@android:color/holo_blue_dark"
android:height="35dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:textIsSelectable="true"
android:textStyle="bold"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<ImageView
android:id="@+id/trainingpass_showhide_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_dark"
android:height="25dp"
android:minWidth="50dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:padding="7dp"
android:layout_alignBottom="@+id/trainingpass_headline"
android:src="@mipmap/arrows_up_down"
android:layout_alignParentTop="true" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/trainingpass_headline"
android:layout_alignLeft="@+id/trainingpass_headline"
android:layout_alignStart="@+id/trainingpass_headline"
android:id="@+id/trainingPassContainer"
android:background="@color/blue_bg_neutral"
android:visibility="visible"
android:paddingBottom="10dp">
<EditText
android:id="@+id/trainingpass_exercise_searchfield"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Name of exercise"
android:padding="6dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:background="@color/blue_bg_inputField"
android:layout_margin="10dp" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/trainingpass_exercise_searchfield"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/sets_container"
android:background="@color/blue_bg_inputField"
android:padding="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/txt_sets_for_exercise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sets for exercise"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingBottom="10dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/add_set_button"
android:layout_alignEnd="@+id/add_set_button" />
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/trainingpass_sets_listview"
android:nestedScrollingEnabled="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignTop="@+id/txt_no_sets"
android:layout_alignBottom="@+id/txt_no_sets" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add set"
android:id="@+id/add_set_button"
android:layout_below="@+id/trainingpass_sets_listview"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add exercise"
android:id="@+id/add_exercise_button"
android:layout_below="@+id/add_set_button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<TextView
android:id="@+id/txt_no_sets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No sets yet"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="10dp"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/txt_sets_for_exercise"
android:visibility="invisible" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/sets_container"
android:id="@+id/exercises_container"
android:background="@color/blue_bg_inputField"
android:padding="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/txt_exercises"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Exercises"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingBottom="10dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/txt_no_exercises_yet"
android:layout_alignEnd="@+id/txt_no_exercises_yet" />
<TextView
android:id="@+id/txt_no_exercises_yet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No exercises yet"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="10dp"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:layout_below="@+id/txt_exercises"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/exercises_listview"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/txt_exercises"
android:layout_alignBottom="@+id/txt_no_exercises_yet" />
</RelativeLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"
android:id="@+id/delete_trainingpass_button"
android:layout_alignRight="@+id/exercises_container"
android:layout_alignEnd="@+id/exercises_container"
android:layout_below="@+id/exercises_container"
android:background="@color/btn_red"
android:layout_marginLeft="10dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Done"
android:id="@+id/done_trainingpass_button"
android:layout_below="@+id/exercises_container"
android:layout_alignLeft="@+id/exercises_container"
android:layout_alignStart="@+id/exercises_container"
android:layout_toStartOf="@+id/delete_trainingpass_button"
android:background="@color/btn_green"
android:layout_marginRight="10dp" />
</RelativeLayout>
</RelativeLayout>
我真的希望有人能看到问题所在。
任何帮助将不胜感激。
我认为这种行为是可以预测的,因为适配器利用视图用新数据替换其内容。由于您没有在 getView() 方法中为 EditText 设置新的文本值,因此您将获得具有旧值的 EditText,即您输入的值。
因此,请尝试将 TextWatcher 添加到您的 EditText 并将输入的值保存在相应的 TrainingPass 对象实例中。在 getView() 方法中,您必须添加 holder.exerciseSearchField.setText()。如果相应的 TrainingPass 对象包含先前输入的值,则必须将其设置为 EditText,否则必须设置空字符串。
@Oleg Osipenko 说这是因为列表视图 reuse/recycle.. 示例
class Items {
String name;
String searchField=""; //to stored edit text values , init with empty string
//create getter and setter
}
适配器的 getView()
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.your_adapter_layout, null);
holder.textView1 = (TextView) convertView.findViewById(R.id.textView1);
holder.editText1 = (EditText) convertView.findViewById(R.id.editText1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//holder.position to store view position
holder.position= position;
item=items.get(position);
holder.textView1.setText(item.getName());
holder.editText1.setText(item.getSearchField());
holder.editText1.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
//set more conditions if needed - like arg0=null, or empty
items.get(holder.position).setSearchField(arg0.toString());
}
});
return convertView;
}
private class ViewHolder {
TextView textView1;
EditText editText1;
int position;
}
获取有关此次访问的简要说明:Creating ListView with EditText and TextWatcher in Android
我的列表视图及其自定义适配器遇到了一些奇怪的问题(我认为)。
问题是我的列表视图中的每个项目都有一些不同的视图元素,例如 EditText 字段等。 每当我在列表视图中有超过 2 个项目时,这些元素的条目现在在所有其他项目中。
我举个例子: - 我正在向列表视图中添加 8 个项目。 - 我在第一个文本字段中输入一个值 - 现在在文本字段中重复相同的值:3、5 和 7 - 如果我在第二个项目的文本字段中输入一个值,该值将在项目编号的文本字段中重复:4、6 和 8
希望你现在能看到问题。
这里是这个问题的一些相关代码:
首先,我的自定义适配器 (CreateProgramAdapter) 的代码:
public class CreateProgramAdapter extends BaseAdapter {
private LayoutInflater inflater;
private ArrayList<TrainingPass> trainingPasses;
private List<TrainingPass> items;
private int layoutResourceId;
private Context context;
public CreateProgramAdapter(Context context, List<TrainingPass> items) {
this.context = context;
this.items = items;
this.inflater = LayoutInflater.from(this.context);
}
@Override
public int getCount() {
return items.size();
}
@Override
public TrainingPass getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
TrainingPassHolder holder;
if(convertView == null) {
view = inflater.inflate(R.layout.adapter_createprogram_trainingpasses_item, parent, false);
holder = new TrainingPassHolder();
view.setTag(holder);
} else {
view = convertView;
holder = (TrainingPassHolder)view.getTag();
}
holder.trainingPass = this.getItem(position);
holder.trainingPass.trainingPassID = position + 1;
holder.trainingPassContainer = (RelativeLayout) view.findViewById(R.id.trainingPassContainer);
holder.trainingPassHeadlineShowHide = (TextView) view.findViewById(R.id.trainingpass_headline);
holder.noExercisesYet = (TextView) view.findViewById(R.id.txt_no_exercises_yet);
holder.exerciseSearchField = (EditText) view.findViewById(R.id.trainingpass_exercise_searchfield);
holder.trainingPassSetsListView = (ListView) view.findViewById(R.id.trainingpass_sets_listview);
holder.exercisesListView = (ListView) view.findViewById(R.id.exercises_listview);
holder.addSetButton = (Button) view.findViewById(R.id.add_set_button);
holder.addExerciseButton = (Button) view.findViewById(R.id.add_exercise_button);
holder.deleteTrainingpass = (Button) view.findViewById(R.id.delete_trainingpass_button);
holder.doneTrainingpass = (Button) view.findViewById(R.id.done_trainingpass_button);
setupItems(holder);
return view;
}
private void setupItems(TrainingPassHolder trainingPassHolder) {
final TrainingPassHolder holder = trainingPassHolder;
int trainingPassID = trainingPassHolder.trainingPass.trainingPassID;
TextView showHide = holder.trainingPassHeadlineShowHide;
Button addSet = holder.addSetButton;
Button deleteTrainingPass = holder.deleteTrainingpass;
final EditText exerciseNameField = holder.exerciseSearchField;
// Set title of the trainingpass
showHide.setText("Trainingpass " + trainingPassID);
// Set name of exercise
if (trainingPassHolder.trainingPass.tempExerciseName != null) {
System.out.println(holder.trainingPass.tempExerciseName);
exerciseNameField.setText(holder.trainingPass.tempExerciseName);
} else {
exerciseNameField.setText("");
}
// Add 1 default set to exercise
if (holder.sets.size() == 0) {
holder.sets.add(1);
}
/*
Set adapter for sets of the listview for the trainingpass
*/
final TrainingPassSetsAdapter createProgramAdapter = new TrainingPassSetsAdapter(context, holder.sets);
holder.trainingPassSetsListView.setAdapter(createProgramAdapter);
exerciseNameField.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
holder.trainingPass.tempExerciseName = exerciseNameField.getText().toString();
return false;
}
});
/*
Show / hide the trainingpass
*/
showHide.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.trainingPass.visible) {
holder.trainingPass.visible = false;
holder.trainingPassContainer.setVisibility(View.GONE);
} else {
holder.trainingPass.visible = true;
holder.trainingPassContainer.setVisibility(View.VISIBLE);
}
}
});
/*
Add set to the listview
*/
addSet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.sets.add(1);
createProgramAdapter.notifyDataSetChanged();
}
});
/*
Delete training pass
*/
deleteTrainingPass.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
items.remove(holder.trainingPass);
notifyDataSetChanged();
}
});
}
private static class TrainingPassHolder {
ArrayList<Integer> sets = new ArrayList<Integer>();
TrainingPass trainingPass;
RelativeLayout trainingPassContainer;
TextView trainingPassHeadlineShowHide;
TextView noExercisesYet;
EditText exerciseSearchField;
ListView trainingPassSetsListView;
ListView exercisesListView;
Button addSetButton;
Button addExerciseButton;
Button deleteTrainingpass;
Button doneTrainingpass;
}
}
这里是 class TrainingPass 的代码:
public class TrainingPass {
public String trainingPassName;
public ArrayList<Exercise> exercises;
public int trainingPassID;
public boolean visible = false;
public String tempExerciseName;
public TrainingPass() {
exercises = new ArrayList<Exercise>();
}
public void addExercise(Exercise exercise ) {
exercises.add(exercise);
}
}
activity class CreateProgramActivity 的代码:
public class CreateProgramActivity extends CustomActivity {
private ArrayList<TrainingPass> trainingPasses;
private CreateProgramAdapter createProgramAdapter;
private ListView trainingPassesListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_program);
trainingPasses = new ArrayList<TrainingPass>();
trainingPassesListView = (ListView)findViewById(R.id.listView_trainingpasses);
createProgramAdapter = new CreateProgramAdapter(CreateProgramActivity.this, trainingPasses);
trainingPassesListView.setAdapter(createProgramAdapter);
}
public void addTrainingPass(View v) {
TrainingPass trainingPass = new TrainingPass();
trainingPasses.add(trainingPass);
createProgramAdapter.notifyDataSetChanged();
}
public void addTrainingPassHelp(View v) {
Toast.makeText(this, "Add training pass HELP!", Toast.LENGTH_SHORT).show();
}
public void createProgram(View v) {
Toast.makeText(this, "Create program", Toast.LENGTH_SHORT).show();
}
}
这是 CreateProgramActivity 的 xml 布局,包含父列表视图:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mobileplatformexam.activities.CreateProgramActivity"
android:id="@+id/relativeLayoutCreateProgram">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add training pass"
android:id="@+id/btn_add_trainingpass"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@+id/btn_add_trainingpass_help"
android:layout_toStartOf="@+id/btn_add_trainingpass_help"
android:onClick="addTrainingPass"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="\?"
android:id="@+id/btn_add_trainingpass_help"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:onClick="addTrainingPassHelp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create program"
android:id="@+id/btn_create_program"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/btn_add_trainingpass_help"
android:layout_alignEnd="@+id/btn_add_trainingpass_help"
android:onClick="createProgram"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView_trainingpasses"
android:layout_above="@+id/btn_create_program"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/btn_add_trainingpass" />
</RelativeLayout>
最后,这是我的 xml 父列表视图项目的布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/trainingpass_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="false"
android:layout_alignParentTop="true"
android:text="Trainingpass"
android:textSize="16dp"
android:textColor="@android:color/white"
android:background="@android:color/holo_blue_dark"
android:height="35dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:textIsSelectable="true"
android:textStyle="bold"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<ImageView
android:id="@+id/trainingpass_showhide_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_dark"
android:height="25dp"
android:minWidth="50dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:padding="7dp"
android:layout_alignBottom="@+id/trainingpass_headline"
android:src="@mipmap/arrows_up_down"
android:layout_alignParentTop="true" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/trainingpass_headline"
android:layout_alignLeft="@+id/trainingpass_headline"
android:layout_alignStart="@+id/trainingpass_headline"
android:id="@+id/trainingPassContainer"
android:background="@color/blue_bg_neutral"
android:visibility="visible"
android:paddingBottom="10dp">
<EditText
android:id="@+id/trainingpass_exercise_searchfield"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Name of exercise"
android:padding="6dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:background="@color/blue_bg_inputField"
android:layout_margin="10dp" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/trainingpass_exercise_searchfield"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/sets_container"
android:background="@color/blue_bg_inputField"
android:padding="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/txt_sets_for_exercise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sets for exercise"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingBottom="10dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/add_set_button"
android:layout_alignEnd="@+id/add_set_button" />
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/trainingpass_sets_listview"
android:nestedScrollingEnabled="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignTop="@+id/txt_no_sets"
android:layout_alignBottom="@+id/txt_no_sets" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add set"
android:id="@+id/add_set_button"
android:layout_below="@+id/trainingpass_sets_listview"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add exercise"
android:id="@+id/add_exercise_button"
android:layout_below="@+id/add_set_button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<TextView
android:id="@+id/txt_no_sets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No sets yet"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="10dp"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/txt_sets_for_exercise"
android:visibility="invisible" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/sets_container"
android:id="@+id/exercises_container"
android:background="@color/blue_bg_inputField"
android:padding="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/txt_exercises"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Exercises"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingBottom="10dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/txt_no_exercises_yet"
android:layout_alignEnd="@+id/txt_no_exercises_yet" />
<TextView
android:id="@+id/txt_no_exercises_yet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No exercises yet"
android:textSize="14dp"
android:textColor="@android:color/black"
android:paddingRight="30dp"
android:paddingLeft="10dp"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:layout_below="@+id/txt_exercises"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/exercises_listview"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/txt_exercises"
android:layout_alignBottom="@+id/txt_no_exercises_yet" />
</RelativeLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"
android:id="@+id/delete_trainingpass_button"
android:layout_alignRight="@+id/exercises_container"
android:layout_alignEnd="@+id/exercises_container"
android:layout_below="@+id/exercises_container"
android:background="@color/btn_red"
android:layout_marginLeft="10dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Done"
android:id="@+id/done_trainingpass_button"
android:layout_below="@+id/exercises_container"
android:layout_alignLeft="@+id/exercises_container"
android:layout_alignStart="@+id/exercises_container"
android:layout_toStartOf="@+id/delete_trainingpass_button"
android:background="@color/btn_green"
android:layout_marginRight="10dp" />
</RelativeLayout>
</RelativeLayout>
我真的希望有人能看到问题所在。
任何帮助将不胜感激。
我认为这种行为是可以预测的,因为适配器利用视图用新数据替换其内容。由于您没有在 getView() 方法中为 EditText 设置新的文本值,因此您将获得具有旧值的 EditText,即您输入的值。 因此,请尝试将 TextWatcher 添加到您的 EditText 并将输入的值保存在相应的 TrainingPass 对象实例中。在 getView() 方法中,您必须添加 holder.exerciseSearchField.setText()。如果相应的 TrainingPass 对象包含先前输入的值,则必须将其设置为 EditText,否则必须设置空字符串。
@Oleg Osipenko 说这是因为列表视图 reuse/recycle.. 示例
class Items {
String name;
String searchField=""; //to stored edit text values , init with empty string
//create getter and setter
}
适配器的 getView()
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.your_adapter_layout, null);
holder.textView1 = (TextView) convertView.findViewById(R.id.textView1);
holder.editText1 = (EditText) convertView.findViewById(R.id.editText1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//holder.position to store view position
holder.position= position;
item=items.get(position);
holder.textView1.setText(item.getName());
holder.editText1.setText(item.getSearchField());
holder.editText1.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
//set more conditions if needed - like arg0=null, or empty
items.get(holder.position).setSearchField(arg0.toString());
}
});
return convertView;
}
private class ViewHolder {
TextView textView1;
EditText editText1;
int position;
}
获取有关此次访问的简要说明:Creating ListView with EditText and TextWatcher in Android