2015-07-28 51 views
0

我想弄清楚如何“刷新”列表视图当用户在我的列表视图中的项目被删除时。我已经尝试notifyDataSetChanged()但无济于事,这是令我费解的,因为这在我添加项目时起作用。ListView不“刷新”后,从项目中删除

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会出现。

公共类CustomExerciseAdapter扩展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); 

} 
+1

为什么在OnClick中设置Adapter(使用setAdapter方法)? – GVillani82

+1

张贴您的适配器。它是直接从数据库中获取数据吗? – FWeigl

+2

在重新加载适配器之后调用'notifyDataSetChanged()'是没有意义的...您是否正在重新加载它? –

回答

0

感谢所有帮助的人,但最终我提出的答案与您的答案完全不同。我结束了他的方法[1]:http://jmsliu.com/2444/click-button-in-listview-and-get-item-position.html/“这里”,这对我来说非常完美。无论如何,这是谁可能遇到同样的问题。

将此代码粘贴到GetView()方法中。位于.JAVA文件中用于扩展XML文件。

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

然后删除项目随时添加下面两行

  notifyDataSetChanged(); 
      notifyDataSetInvalidated(); 

notifydatasetchanged将看到任何更改后添加到您的按钮,点击监听器/ OnClick方法

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

    adapter.notifyDataSetChanged(); 
1

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

+0

对不起,这可能是一个愚蠢的问题,但你在哪里使用CursorAdapter.chageCursor? –

+0

[在我写的刷新ListView的方法中,在数据库查询之后。](https://github.com/nkorth/AndroidNotepad/blob/master/src/com/nkorth/notepad/TextListFragment.java#L183-L189 ) – nkorth

1

您的项目正在从数据库中删除,但listview没有可视化更新。设置适配器是一个解决方案,但它会重置列表从开始,这不是一个很好的体验,让用户再次滚动所有的时间。你可以做从数据库中删除项目的同时,您可以从列表中删除所选项目。我觉得你的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(); 
    } 
} 
+0

感谢您的建议,对不起,这可能是一个愚蠢的问题,但我很新(3天前开始)。我似乎遇到了list.remove(position)的困难。你从哪里得到这个位置变量? –

+0

嘿,你可以粘贴你的适配器整个代码? –

+0

我做了,而不是使用位置我传递的字符串我想从列表中删除但它似乎仍然没有工作。这里是我改变了 'dbHandler.deleteExerciseFromDatabase(exerciseClickedbyUser,workoutClicked); itemHold.remove(exerciseClickedbyUser); edsAdapter.notifyDataSetChanged();' –

0

你似乎在列表视图中没有变化,因为你的ArrayList或阵列您分配给适配器没有变化。请从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(锻炼),.它可能会为你做诡计。

+0

嗨@Ansal Ali,我添加了以下itemHold.remove(exerciseClickedbyUser); edsAdapter.notifyDataSetChanged();但我似乎得到相同的结果。有什么我错过了 –

+0

删除edsAdapter.notifyDataSetChanged(); from不会对你的listview有任何影响。请检查并确认。 –

+0

如果没有任何影响意味着视图保持不变并且“未刷新”,那么是的,没有影响 –

0

这在列表 和notifydatasetinvalidated将检查是否有任何项目重新移动然后它将更新列表

1

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

mCollection.remove(position); 
mListLayout.removeAllViews(); 
notifyDataSetChanged(); 
相关问题