2015-07-28 52 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(); 
相關問題