具有自定义适配器的listview-其他所有item元素均重复 [英] listview with a custom adapter - every other item element are duplicates

查看:65
本文介绍了具有自定义适配器的listview-其他所有item元素均重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的列表视图及其自定义适配器中遇到了一个奇怪的问题(我认为).

I have come accross a bit of a weird problem (i think) with my listview and its customadapter.

问题是我的列表视图中的每个项目都有一些不同的视图元素,例如EditText字段等. 只要列表视图中有2个以上的项目,这些元素的条目就会出现在其他所有项目中.

The problem is that I have some different view elements for every item in my listview, such as EditText fields among others. Whenever I have more than 2 items in the listview, entries to these elements are now in every other item.

让我举个例子: -我将8个项目添加到列表视图中. -我在第一个文本字段中输入了一个值 -现在在文本字段中重复相同的值:3、5和7 -如果我在第二个项目的文本字段中输入一个值,则会在项目编号为4、6和8的文本字段中重复该值

Let me give an example: - I am adding 8 items to the listview. - I enter a value in the first textfield - Now the same value repeats in the textfields: 3, 5 and 7 - If I enter a value in the second item's textfield, this value is repeated in textfield of item number: 4, 6 and 8

希望您现在能看到问题.

I hope that you can see the problem now.

以下是此问题的一些相关代码:

Here is some of the relevant code for this problem:

首先,我的customadapter(CreateProgramAdapter)的代码:

First, the code for my customadapter (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;
    }
}

这是TrainingPass类的代码:

And here is the code for the 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);
    }

}

活动类CreateProgramActivity的代码:

An the code for the 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布局,其中包含父列表视图:

Here is the xml layout for the CreateProgramActivity, containing the parent listview:

<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布局:

And lastly, here is my xml layout for the item of the parent listview:

<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>

我真的希望有人能看到问题所在.

I really hope that someone can see what the problem is.

任何帮助将不胜感激.

推荐答案

我认为这种行为是可以预见的,因为适配器利用视图将其内容替换为新数据.由于您没有在 getView()方法中将新文本值设置为EditText,因此您将获得具有旧值的EditText,即您输入的值. 因此,尝试将TextWatcher添加到您的EditText中,并将输入的值保存在TrainingPass对象的相应实例中.在getView()方法中,您必须添加 holder.exerciseSearchField.setText().如果相应的TrainingPass对象包含先前输入的值,则必须将其设置为EditText,否则必须设置空字符串.

I think this behavior is predictable as adapter utilizes views replacing its content with new data. As you didn't set new text value to EditText in the getView() method you get EditText with old value, which is that you entered. So try to add TextWatcher to your EditText and save entered value in the corresponding instance of TrainingPass object. And in the getView() method you have to add of holder.exerciseSearchField.setText(). If corresponding TrainingPass object contains previously entered value you have to set it to EditText, otherwise you have to set empty string.

这篇关于具有自定义适配器的listview-其他所有item元素均重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆