从中删除项目后,ListView不会“刷新”

时间:2015-07-28 08:45:04

标签: android android-layout layout android-listview adapter

我想弄清楚当我的listview中的项目被删除时,我如何“刷新”用户所在的列表视图。我已经尝试过notifyDataSetChanged(),但无济于事,这对我来说很困惑,因为当我添加一个项目时这是有效的。

P.S。我知道该项目已被删除,因为如果我按下后退按钮并再次进入我的活动,该项目将从列表视图中直观删除。

    public void deleteButtonClicked(View view){
    dbHandler.deleteExerciseFromDatabase(exerciseClickedbyUser, workoutClicked);
    exerciseListView.setAdapter(edsAdapter);
    edsAdapter.notifyDataSetChanged();
    Toast.makeText(getBaseContext(),"Exercise Deleted", Toast.LENGTH_SHORT).show();

}

当我在模拟器中运行它时,会出现Toast。

public class CustomExerciseAdapter extends ArrayAdapter {

public CustomExerciseAdapter(Context context, ArrayList<String> workouts) {
    super(context, R.layout.exercise_custom_row, workouts);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View customView = inflater.inflate(R.layout.exercise_custom_row, parent, false);

    String singleExerciseItem = getItem(position);
    TextView exerciseTV = (TextView) customView.findViewById(R.id.exerciseTV);
    exerciseTV.setText(singleExerciseItem);

    return customView;
}

这是我的类包含deleteButtonClicked

public class ExercisesSection extends ActionBarActivity {

private EditText userWorkoutInput;
private Button addNewWorkoutButton;
private CustomExerciseAdapter edsAdapter;
private ArrayList<String> itemHold;
private MyDBHandler dbHandler;
private String workoutClicked;
private String exerciseClickedbyUser;
private ListView exerciseListView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getSupportActionBar().hide();
    setContentView(R.layout.activity_exercises_section);

    initViews();
    handleIntentData();
    inputTextHandler();
    loadDataFromDatabase();


}
//This method initializes all the views
public void initViews(){
    userWorkoutInput = (EditText) findViewById(R.id.userWorkoutInput);
    addNewWorkoutButton = (Button) findViewById(R.id.addNewWorkoutButton);
    exerciseListView = (ListView) findViewById(R.id.exerciseListView);
    itemHold = new ArrayList<String>();
    dbHandler = new MyDBHandler(this,null,null,1);
}

//This method makes the "Add new workout Button" clickable or not depending on user input
public void inputTextHandler(){

    userWorkoutInput.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) {
                    boolean isEmpty = false;
                    if ((userWorkoutInput.getText().toString().trim()).equals("")) {
                        isEmpty = true;
                    }
                    addNewWorkoutButton.setEnabled(!isEmpty);
                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            }
    );
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
THIS IS THE BUTTON LISTENER FOR @id+/addNewWorkoutButton
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
public void addWorkoutButtonClicked(View view){
    String input = (userWorkoutInput.getText().toString().trim());
    if (!input.equals("")){
        addItemToList(input);
        userWorkoutInput.setText("");   //Empties the edit text section
        saveDataToDatabase(input);
    }
}

public void saveDataToDatabase(String input){
    //GIVE THE EXERCISES OBJ VALUES!
    Exercises exercises = new Exercises(input, workoutClicked);
    dbHandler.addExerciseToDatabase(exercises);
}

public void loadDataFromDatabase(){

    String exerName = dbHandler.getExercisesForBodyParts(workoutClicked);

    //IF STATEMENT WEEDS OUT EMPTY DATA
    if(!(exerName.trim().equals(""))) {
        String delim = ",";
        String[] tokens = exerName.split(delim);
        for (int i = 0; i < tokens.length; i++) {
            addItemToList(tokens[i]);
        }
    }
}

public void addItemToList(String input){

    itemHold.add(input);
    edsAdapter = new CustomExerciseAdapter(this, itemHold);

    exerciseListView.setAdapter(edsAdapter);
    edsAdapter.notifyDataSetChanged();

    exerciseListView.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    exerciseClickedbyUser = String.valueOf(parent.getItemAtPosition(position));
                    textClicked(view, exerciseClickedbyUser);  //starts intent and sends to Exercise Clicked Activity
                }
            }
    );

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 This method is an onClick Method from exercise_custom_row.xml
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

public void deleteButtonClicked(View view){
    dbHandler.deleteExerciseFromDatabase(exerciseClickedbyUser, workoutClicked);
    itemHold.remove(exerciseClickedbyUser);

    edsAdapter.notifyDataSetChanged();

    Toast.makeText(getBaseContext(),"Exercise Deleted", Toast.LENGTH_SHORT).show();
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 This method gets the data (name of section clicked) from MainActivity
 and changes the textView in exercise_section accordingly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
public void handleIntentData(){

    Bundle workoutData = getIntent().getExtras();
    if (workoutData == null){
        return;
    }

    workoutClicked = workoutData.getString("exerciseChosen");
    TextView exerciseChosenText = (TextView) findViewById(R.id.exerciseChosenText);
    exerciseChosenText.setText(workoutClicked);
    exerciseChosenText.setTypeface(null, Typeface.BOLD);
}



public void textClicked(View view, String exercise){

    Intent i = new Intent(this, ExerciseClicked.class);
    i.putExtra("exerciseClicked", exercise);
    startActivity(i);

}

6 个答案:

答案 0 :(得分:1)

在我的应用中,我根本不使用notifyDataSetChanged。要刷新ListView,我只需再次运行数据库查询并使用CursorAdapter.changeCursor。它会根据需要自动调用notifyDataSetChanged

答案 1 :(得分:1)

您的项目正在从数据库中删除,但列表视图没有直观更新。设置适配器是一个解决方案,但它会从开始重置列表,这不会让用户一直滚动的好体验。你可以做一个从数据库中删除项目的同时,您可以从列表中删除所选项目。我认为你的listview监听器应该在你的活动中看起来像这样:

listview.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                deleteButtonClicked(postion);
            }
        });



public void deleteButtonClicked(int position){
           int count=dbHandler.deleteExerciseFromDatabase(exerciseClickedbyUser, workoutClicked);
    if(count>0){
        list.remove(position);

            edsAdapter.notifyDataSetChanged();
            Toast.makeText(getBaseContext(),"Exercise Deleted", Toast.LENGTH_SHORT).show();
    }
}

答案 2 :(得分:1)

您可以使用以下代码从适配器中完美删除项目。

mCollection.remove(position);
mListLayout.removeAllViews();
notifyDataSetChanged();

答案 3 :(得分:0)

您在listview中似乎没有变化,因为您分配给适配器的ArrayList或Array没有任何更改。请从ArrayList或数组中删除该项。而你只需要调用notifyDataSetChanged()。即,不需要再次调用listview.setAdapter(adapter)。

编辑:

请使用以下显示的代码替换您的customArrayAdapter

   private  ArrayList<String> workouts;

    public CustomExerciseAdapter(Context context, ArrayList<String> workouts) {
        super(context, R.layout.exercise_custom_row, workouts);
        this.workouts = workouts;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        View customView = inflater.inflate(R.layout.exercise_custom_row, parent, false);
                /////here change to 
        String singleExerciseItem = (String)workouts.get(position);
        TextView exerciseTV = (TextView) customView.findViewById(R.id.exerciseTV);
        exerciseTV.setText(singleExerciseItem);

        return customView;
    }


    public void setList(ArrayList<String> workouts){

       this.workouts = workouts;
       notifyDatasetChanged();

    }
}

在删除方法中,更新数据库和列表后,调用adapter.setList(workouts)。它可能会为你做到这一点。

答案 4 :(得分:0)

感谢所有帮助人员,但最终我想出的答案与你的完全不同。我最终使用他的方法[1]:http://jmsliu.com/2444/click-button-in-listview-and-get-item-position.html/&#34;这里&#34;这对我来说绝对是完美的。无论如何,这对于那些可能遇到同样问题的人来说也是如此。

位于.JAVA文件中的GetView()方法中的这个代码会影响XML文件。

Button deleteButton = (Button) customView.findViewById(R.id.deleteButton);
deleteButton.setTag(position);

然后将其添加到按钮单击侦听器/ onClick方法

    int position = (Integer) view.getTag();
    list.remove(position);

    adapter.notifyDataSetChanged();

答案 5 :(得分:0)

删除项目后,请始终添加以下两行

assign <wire1> = <2-bit_select> ? <value0> : <2-bit_select> ? <value1> : ... <value1>;

notifydatasetchanged将查看列表中的任何更改 并且notifydatasetinvalidated将检查是否有任何项目被删除然后它将更新列表