簡體   English   中英

調用notifyDataSetChanged()時,RecyclerView不會更新或刷新

[英]RecyclerView does not update or refresh when calling notifyDataSetChanged()

IronMax app屏幕截圖

我有一個使用RecyclerView的應用程序。 當用戶從選項菜單中選擇“添加新行”時,我將測試消息輸出到屏幕,並將一些值附加到兩個不同的ArrayLists。 這部分工作得很好,因為我已經確認通過使用調試器查看ArrayList值來成功添加這些值。

無論如何,我無法讓RecyclerView重繪屏幕並顯示新信息。 我嘗試重繪/更新屏幕是使用此代碼(MainActivity.java的第78行):

//call notify data set changed method for the adapter
  adapter.notifyDataSetChanged();

也許我沒有在實際用於RecycleView的同一個適配器上調用notifyDataSetChanged?

以下是MainActivity.java的完整代碼(請參閱末尾的選項菜單代碼):

package com.joshbgold.ironmax;

import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int ADD_ROW = 1;  //used for case statement statement to select menu item
    private RecyclerView recyclerView;
    public Exercises exercises = new Exercises();
    public ExerciseRow adapter;

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

        assert getSupportActionBar() != null;
        ActionBar actionBar = getSupportActionBar();

        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setIcon(R.mipmap.barbell);
        actionBar.setTitle("  " + "Iron Max");

        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        //ExerciseRow adapter = new ExerciseRow(this);
        adapter = new ExerciseRow(this);
        recyclerView.setAdapter(adapter);

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        recyclerView.setHasFixedSize(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

       /* MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.add_row, menu);
        return super.onCreateOptionsMenu(menu);*/

        menu.add(0, ADD_ROW, 0, "Add New Row");
        menu.getItem(0).setIcon(R.drawable.plus);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.getItem(0).setIcon(R.drawable.plus);

        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int length;

        switch (item.getItemId()) {
            case 1:
                Toast msg = Toast.makeText(MainActivity.this, "Test code for adding an exercise", Toast.LENGTH_LONG);
                msg.show();

                exercises.addExercise("Some exercise");
                exercises.addPersonalBest(500);
                length = exercises.getExercisesArrayLength();

               //call notify data set changed method for the adapter
                adapter.notifyItemInserted(length - 1);
                adapter.notifyDataSetChanged();

                return super.onOptionsItemSelected(item);


            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

這是Exercises.java:

import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;

public class Exercises extends AppCompatActivity {

    public ArrayList<String> exercisesArrayList = new ArrayList<>();  //stores all the lifts

    private ArrayList<Integer> personalBestsArrayList = new ArrayList<>();  //stores personal bests in pounds

    public ArrayList<String> getExercisesArray() {   //returns the whole exercises arraylist
        return exercisesArrayList;
    }

    public ArrayList<Integer> getPersonalBests() {  //returns the whole personal bests arraylist
        return personalBestsArrayList;
    }

    public String getExercise(int position) {  //returns individual exercise from array
        return exercisesArrayList.get(position);
    }

    public void addExercise(String exercise) {
        exercisesArrayList.add(exercise);
    }

    public void removeExercise(int position) {
        exercisesArrayList.remove(position);
    }

    public void editExercise(int position, String exercise) {
        exercisesArrayList.set(position, exercise);
    }

    public int getExercisesArrayLength() {
        return exercisesArrayList.size();
    }


    public Integer getPersonalBest(int position) {  //returns individual personal best from array
        return personalBestsArrayList.get(position);
    }

    public void addPersonalBest(int personalBest) {
        personalBestsArrayList.add(personalBest);
    }

    public void removePersonalBest(int position) {
        personalBestsArrayList.remove(position);
    }

    public void editPersonalBest(int position, int personalBest) {
        personalBestsArrayList.set(position, personalBest);
    }

    public Exercises() {} //constructor
}

這是ExerciseRow.java:

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class ExerciseRow extends RecyclerView.Adapter<ExerciseRow.ExerciseViewHolder> {

    String exerciseName = "burpee";
    String exercisePR = "100";  // user's personal record for this exercise in pounds

    private Context context;
    Exercises exercises = new Exercises();


    public ExerciseRow(Context context) {
        this.context = context;
    }

    @Override
    public ExerciseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.exercise_list_item, parent, false);
        return new ExerciseViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ExerciseViewHolder holder, int position) {
        ArrayList<String> exercisesArray = exercises.getExercisesArray();
        holder.bindExercises(exercisesArray.get(position));
    }

    @Override
    public int getItemCount() {
        return exercises.getExercisesArrayLength();
    }

    public class ExerciseViewHolder extends RecyclerView.ViewHolder {

        public TextView exerciseNameTextView;
        public TextView personalRecordTextView;
        public ImageView edit_Icon;
        public ImageView percentages_Icon;
        public ImageView trash_Icon;
        public ImageView plus_icon;
        public ImageView facebook_icon;
        public ImageView twitter_icon;

        public ExerciseViewHolder(View itemView) {
            super(itemView);

            exerciseNameTextView = (TextView) itemView.findViewById(R.id.list_item_exercise_textview);
            personalRecordTextView = (TextView) itemView.findViewById(R.id.list_item_amount_textview);
            edit_Icon = (ImageView) itemView.findViewById(R.id.list_item_pencil);
            percentages_Icon = (ImageView) itemView.findViewById(R.id.list_item_percent);
            trash_Icon = (ImageView) itemView.findViewById(R.id.list_item_trash);
            plus_icon = (ImageView) itemView.findViewById(R.id.list_item_plus);
            facebook_icon = (ImageView) itemView.findViewById(R.id.list_item_facebook);
            twitter_icon = (ImageView) itemView.findViewById(R.id.list_item_twitter);

            View.OnClickListener plus = new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // allow user to add a new exercise and personal best
                    exercises.addExercise("Some exercise");
                    exercises.addPersonalBest(500);
                    notifyDataSetChanged();
                }
            };

            View.OnClickListener edit = new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getLayoutPosition();  //use getAdapterPosition() if getLayoutPosition causes a problem

                    if (position == 0) {  //prevent user from deleting the first row.
                        Toast.makeText(context, "Sorry, example row cannot be edited.", Toast.LENGTH_LONG).show();
                    }
                    else{
                        editRow(position);  //edit the row at the current position
                        notifyDataSetChanged();
                    }
                }
            };

            View.OnClickListener percentages = new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //get exercise name
                    exerciseName = exerciseNameTextView.getText().toString();
                    exercisePR = personalRecordTextView.getText().toString();

                    //show percentages layout
                    startPercentagesActivity(exerciseName, exercisePR);
                }
            };

            View.OnClickListener trash = new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getLayoutPosition();  //use getAdapterPosition() if getLayoutPosition causes a problem

                    if (position == 0) {  //prevent user from deleting the first row.
                        Toast.makeText(context, "Sorry, example row cannot be deleted.", Toast.LENGTH_LONG).show();
                    } else {
                        exercises.removeExercise(position);
                        exercises.removePersonalBest(position);
                        notifyItemRemoved(position);
                        notifyItemRangeChanged(position, exercises.getExercisesArrayLength());
                    }
                }
            };

                plus_icon.setOnClickListener(plus);
                edit_Icon.setOnClickListener(edit);
                percentages_Icon.setOnClickListener(percentages);
                trash_Icon.setOnClickListener(trash);
            }

        public void bindExercises(String exercises) {
            Exercises exercisesObject = new Exercises();
            exerciseNameTextView.setText(exercisesObject.getExercise(getAdapterPosition()));
            personalRecordTextView.setText((exercisesObject.getPersonalBest(getAdapterPosition())).toString() + " pounds");
        }

    }

    private void startPercentagesActivity(String some_exercise, String personal_record) {
        Intent intent = new Intent(context, PercentagesActivity.class);
        intent.putExtra("exerciseName", some_exercise);
        intent.putExtra("personalRecord", personal_record);
        context.startActivity(intent);
    }

    protected void editRow(final int position) {
        LayoutInflater layoutInflater = LayoutInflater.from(context);

        //text_entry is an Layout XML file containing two text field to display in alert dialog
        final View textEntryView = layoutInflater.inflate(R.layout.text_entry, null);
        final EditText liftName = (EditText) textEntryView.findViewById(R.id.liftNameEditText);
        final EditText PersonalBestInPounds = (EditText) textEntryView.findViewById(R.id.personalBestEditText);
        final AlertDialog.Builder alert = new AlertDialog.Builder(context);

        alert.setIcon(R.mipmap.barbell)
                .setTitle("Please make your changes:")
                .setView(textEntryView)
                .setPositiveButton("Save",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {


                                //retrieve the user's input
                                String lift = liftName.getText().toString();
                                int personalBest = Integer.parseInt(PersonalBestInPounds.getText().toString());

                                //save the user's input to the appropriate arrays
                                exercises.editExercise(position, lift);
                                exercises.editPersonalBest(position, personalBest);
                            }
                        })
                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int whichButton) {
                            }
                        });
        alert.show();
    }
}

如果你已經讀過這篇文章,我給你信任! 請理解我對RecyclerView來說是全新的,所以我所做的任何錯誤都可能非常簡單。

問題是你在MainActivity有兩個不同的Exercises One實例,而在ExerciseRow有另一個實例你正在將數據添加到錯誤的實例中。

其他一些可能對您有所幫助的事情。

  1. Exercises不應該擴展AppCompatActivity (或者就我所知的任何事情而言)

  2. 你應該避免保存對上下文的引用(正如你在練習中所做的那樣)它可能會產生很大的內存問題。 而是嘗試以下之一。

    A.使用上下文在構造函數中獲取LayoutInflater

    B.在onCreateViewHolder調用parent.getContext()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM