RecyclerView不会膨胀,而是更新相同的视图?

时间:2018-06-08 12:08:09

标签: java android android-recyclerview realm recycler-adapter

我有一个活动来实现一个待办事项列表,其中包含一个recyclelerview,每个项目都是一个复选框和textview,每个任务都是从一个edittext中添加的。 它使用Realm.io存储数据。我一直得到的行为是,recyclerview中的单个元素只是更新,而不是膨胀!请帮忙。

TasksActivity -

public class TasksActivity extends AppCompatActivity implements View.OnClickListener{

    TextView courseTitle;
    RecyclerView TaskList;
    EditText addTask;
    Button addButton;

    String transName; //Transferred Course name from MainActivity


    TaskAdapter TA;

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

        courseTitle = findViewById(R.id.CourseName);
        TaskList = findViewById(R.id.TaskListRV);
        TaskList.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));


        addTask = findViewById(R.id.InputTask);
        addButton = findViewById(R.id.AddTaskButton);

        //Course name is the obtained from the previous acivity.

        transName =getIntent().getExtras().getString("CourseName");
        courseTitle.setText(transName);

        TA = new TaskAdapter(transName);
        TaskList.setAdapter(TA);

        addButton.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {

        String task = addTask.getText().toString();

        // Checking if the text is empty.

        boolean flag = false;
        for(int i = 0;i<task.length();i++)
        {
            if(task.charAt(i)!=' ')
                flag = true;
        }

        if(!flag || task.equals(""))
        {
            Toast emptyWarning = Toast.makeText(getApplicationContext(),"Task cannot be Empty!",Toast.LENGTH_SHORT);
            emptyWarning.show();
        }
        else
        {
            addTask.setText("");
            TA.addNewTask(task);

        }
    }

}

TasksAdapter -

public class TaskAdapter extends RecyclerView.Adapter<TaskViewHolder> implements RealmChangeListener<RealmResults<TaskModel>>
{

    private ArrayList<TaskModel> TaskList;
    private String course;
    private final Realm realm;



        public TaskAdapter(String course)
        {
            this.course = course;

            this.TaskList = new ArrayList<>();
            realm = Realm.getDefaultInstance();
            loadTaskData();
        }

        void loadTaskData()
        {
            RealmResults<TaskModel> taskModelRealmResults = realm.where(TaskModel.class).equalTo("courseName",course).findAll();
            taskModelRealmResults.addChangeListener(this);

            for(TaskModel iTM : taskModelRealmResults)
            {
                TaskList.add(realm.copyFromRealm(iTM));
            }
            notifyDataSetChanged();

        }

        @Override
        public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
            View view= layoutInflater.inflate(R.layout.item_task,parent,false);

            TaskViewHolder Tvh = new TaskViewHolder(view);
            return Tvh;
        }

        @Override
        public void onBindViewHolder(TaskViewHolder holder, int position) {
            holder.populateTask(TaskList.get(position));

        }

        @Override
        public int getItemCount() {
            return TaskList.size();
        }

        public void addNewTask(String task)
        {
            TaskModel newTaskObj = new TaskModel(task,course,false);

            TaskList.add(newTaskObj);
            notifyDataSetChanged();

            realm.beginTransaction();
            realm.insertOrUpdate(newTaskObj);
            realm.commitTransaction();

        }


        @Override
        public void onChange(RealmResults<TaskModel> taskModels) {

            taskModels = realm.where(TaskModel.class).equalTo("courseName",course).findAll();
            this.TaskList = new ArrayList<>();

            for(TaskModel iTM : taskModels)
            {
                this.TaskList.add(realm.copyFromRealm(iTM));
            }
            notifyDataSetChanged();
        }

    }

TaskViewHolder和TaskModel - (如果您可能需要它们)

public class TaskModel extends RealmObject {

    String task;

    @PrimaryKey
    String courseName;

    boolean isDone;

    public TaskModel() {
        task = "";
        courseName = "";
        isDone = false;
    }

    public TaskModel(String task, String courseName, boolean isDone) {
        this.task = task;
        this.courseName = courseName;
        this.isDone = isDone;
    }


    public String getTask() {
        return task;
    }

    public void setTask(String task) {
        this.task = task;
    }

    public boolean isDone() {
        return isDone;
    }

    public void setDone(boolean done) {
        isDone = done;
    }
}

public class TaskViewHolder extends RecyclerView.ViewHolder  {

    CheckBox isdone;
    TextView Taskname;


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

        isdone = itemView.findViewById(R.id.TaskCheckBox);
        Taskname = itemView.findViewById(R.id.TaskName);

    }

    void populateTask(final TaskModel T)
    {
        Taskname.setText(T.getTask());
        isdone.setChecked(T.isDone());

        isdone.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                T.setDone(isdone.isChecked());
            }
        });
    }

}

2 个答案:

答案 0 :(得分:0)

我建议您使用Realm Android dapter,此适配器负责更新您的应用UI。不需要实现OnChangeListener,您的列表将在插入,删除或编辑后自动更新

使用findAllAsync以阻止UI线程

OrderedRealmCollection<TaskModel> taskModels = realm.where(TaskModel.class).equalTo("courseName", course).findAllAsync();

public RealmAdapter(OrderedRealmCollection<TaskModel> data) {
    super(data, true);
}

编辑:

在可能的情况下,也始终使用异步方法执行此过程。您可以通过以下方式替换 addNewTask 方法:

public void addNewTask(String task) {
     final TaskModel newTaskObj = new TaskModel(task, course, false);

     realm.executeTransactionAsync(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            realm.copyToRealmOrUpdate(newTaskObj);
        }
     });
}

Yous应该有这样的东西:

<强> TasksActivity

public class TasksActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText addTask;

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

        String transName = getIntent().getExtras().getString("CourseName");

        TextView courseTitle = findViewById(R.id.CourseName);
        courseTitle.setText(transName);

        addTask = findViewById(R.id.InputTask);

        findViewById(R.id.AddTaskButton).setOnClickListener(this);

        OrderedRealmCollection<TaskModel> taskModels = Realm.getDefaultInstance().where(TaskModel.class).equalTo("courseName", transName).findAllAsync()
        TaskAdapter adapter = new TaskAdapter(this, taskModels);

        RecyclerView taskList = findViewById(R.id.TaskListRV);
        taskList.setLayoutManager(new LinearLayoutManager(this));
        taskList.setAdapter(adapter);
    }

    @Override
    public void onClick(View view) {

        String task = addTask.getText().toString().trim();

        if (task.trim().isEmpty()) {
            Toast emptyWarning = Toast.makeText(getApplicationContext(),"Task cannot be Empty!",Toast.LENGTH_SHORT);
            emptyWarning.show();
            return;
        }

        addTask.setText("");
        addNewTask(task);
    }

    private void addNewTask(String task) {
        final TaskModel newTaskObj = new TaskModel(task, course, false);
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.copyToRealmOrUpdate(newTaskObj);
            }
        });
    }
}

TaskAdapter

public class TaskAdapter extends RealmRecyclerViewAdapter<TaskModel, TaskViewHolder> {

    private LayoutInflater layoutInflater

    public TaskAdapter(Context context, OrderedRealmCollection<TaskModel> taskModels) {
        super(taskModels, true);

        this.layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new TaskViewHolder(layoutInflater.inflate(R.layout.item_task , parent, false));
    }

    @Override
    public void onBindViewHolder(TaskViewHolder holder, int position) {
        holder.populateTask(getItem(position));
    }
}

答案 1 :(得分:0)

在这里OP。我最终使用了标准的ReacyclerView.Adapter。 问题在于使用Realm的insertOrUpdate方法时,@PrimaryKeycourseName时,这实际上导致它更新了同一对象而不创建新对象! insert()应该已经被使用。 这是插入任务方法-

  public void addNewTask(String task)
{
    boolean flag = false;

    for(int i = 0;i<TaskList.size();i++)
    {
        if(task.equals(TaskList.get(i).getTask()))
        {
            Toast.makeText(context,"Task already exists!",Toast.LENGTH_SHORT).show();
            flag = true;
            break;
        }
    }
    if(!flag)
    {
        TaskModel newTaskObj = new TaskModel();
        newTaskObj.setTask(task);
        newTaskObj.setDone(false);
        newTaskObj.setCourseName(course);

        TaskList.add(newTaskObj);
        notifyDataSetChanged();

        realm.beginTransaction();
        realm.insert(newTaskObj);
        realm.commitTransaction();
    } }

可以在此处找到整个项目,请检查一下- https://github.com/Hariram-R/ToDoList-App