简体   繁体   English

为什么我必须重新启动我的应用程序才能使RecyclerView显示来自SQLite的数据?

[英]Why do I have to restart my app for my RecyclerView to display data from SQLite?

EDIT 1 : I used debugging statements and it turns out that when I add an item to the database it is successful. 编辑1 :我使用调试语句,事实证明,当我向数据库中添加一个项目时,它是成功的。 However, the updateUI() method is not called because what I am launching is a DialogFragment() so my ListActivity does not enter a paused state. 但是,未调用updateUI()方法,因为我正在启动的是DialogFragment(),因此我的ListActivity不会进入暂停状态。 But, if I exit the app and launch again the adapter gets updated. 但是,如果我退出应用程序并再次启动,则适配器会更新。 So now the question becomes how do I update the adapter after exiting the dialog fragment? 因此,现在的问题变成退出对话框片段如何更新适配器?


I'm building a simple list app and added SQLite database to store task object. 我正在构建一个简单的列表应用程序,并添加了SQLite数据库来存储任务对象。 I am successfully adding items to the database, but they do not show up immediately in the RecyclerView I am using to show all tasks. 我已成功将项目添加到数据库,但它们不会立即显示在我用来显示所有任务的RecyclerView中。 It is only when I completely exit from the app and reload that tasks items show up in the RecyclerView. 只有当我完全退出应用程序并重新加载时,任务项目才会显示在RecyclerView中。

ListFragment.java this will create the RecyclerView ListFragment.java这将创建RecyclerView

public class ListFragment extends Fragment {

private static final String DEBUG_LOG = "debug_message";
private static final String ADD_DIALOG = "add_dialog";
private static final int REQUEST_TITLE = 0;
private RecyclerView mRecyclerView;
private TaskAdapter mAdapter;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_list, container, false);

    mRecyclerView = view.findViewById(R.id.the_task_list);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(linearLayoutManager);

    DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), linearLayoutManager.getOrientation());
    mRecyclerView.addItemDecoration(dividerItemDecoration);

    updateUI();

    return view;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(resultCode == Activity.RESULT_OK && requestCode == ListFragment.REQUEST_TITLE) {

        UUID taskId = (UUID) data.getSerializableExtra(EditTaskFragment.EXTRA_TASK_ID);
        String newTaskName = data.getStringExtra(EditTaskFragment.EXTRA_TASK_TITLE);

        if(newTaskName != null) {
            Task task = TaskLab.get(getActivity()).getTask(taskId);
            task.setTitle(newTaskName);
            TaskLab.get(getActivity()).updateTask(task);
        }

        updateUI();
    }

}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.menu_list_item, menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch(item.getItemId()) {
        case R.id.add_new_task:
            FragmentManager manager = getFragmentManager();
            AddTaskFragment dialog = new AddTaskFragment();
            dialog.show(manager, ADD_DIALOG);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}


@Override
public void onResume() {
    super.onResume();
    updateUI();
}


public void updateUI() {

    // Retrieves ArrayList<Task>
    List<Task> taskList = TaskLab.get(getActivity()).getTaskList();

    if(mAdapter == null) {
        mAdapter = new TaskAdapter(taskList);
        mRecyclerView.setAdapter(mAdapter);

    }else {
        mAdapter.setCrimes(taskList);
        mAdapter.notifyDataSetChanged();
    }
}

private class TaskAdapter extends RecyclerView.Adapter<TaskHolder>{

    private List<Task> mTaskList;

    public TaskAdapter(List<Task> taskList) {

        mTaskList = taskList;
    }

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

    @Override
    public void onBindViewHolder(TaskHolder holder, int position) {
        final Task currentTask = mTaskList.get(position);
        holder.bindData(currentTask);

        final TextView taskTitle = holder.mTaskTitle;

        holder.mSolved.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
               if(isChecked) {
                   taskTitle.setPaintFlags(taskTitle.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
                   currentTask.setSolved(true);
               }else {
                   taskTitle.setPaintFlags(taskTitle.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
               }
            }
        });
    }

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

    public void setCrimes(List<Task> taskList) {
        mTaskList = taskList;
    }
}

private class TaskHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    private Task mTask;
    private TextView mTaskTitle;
    private CheckBox mSolved;

    private static final String EDIT_DIALOG = "edit_dialog";

    public TaskHolder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);

        mTaskTitle = itemView.findViewById(R.id.task_title);
        mSolved = itemView.findViewById(R.id.task_solved);
    }

    public void bindData(Task task) {
        mTask = task;
        mTaskTitle.setText(mTask.getTitle());
        mSolved.setChecked(mTask.isSolved());
    }

    @Override
    public void onClick(View view) {
        if(!mSolved.isChecked()) {
            FragmentManager manager = getFragmentManager();
            EditTaskFragment dialog = EditTaskFragment.newInstance(mTask.getId());
            dialog.setTargetFragment(ListFragment.this, REQUEST_TITLE);
            dialog.show(manager, EDIT_DIALOG);
        }
    }

}

AddTaskFragment.java this will allow the user to add a task item to the RecyclerView AddTaskFragment.java,这将允许用户将任务项添加到RecyclerView

public class AddTaskFragment extends DialogFragment {

private EditText mTaskTitle;

private void addTask() {

    if(!mTaskTitle.getText().toString().equals("")) {
        Task task = new Task();
        task.setTitle(mTaskTitle.getText().toString());

        TaskLab.get(getActivity()).addTask(task);
    }
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    //return super.onCreateDialog(savedInstanceState);

    View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_task_dialog,null);
    mTaskTitle = view.findViewById(R.id.task_title);

    return new AlertDialog.Builder(getActivity())
            .setView(view)
            .setTitle(R.string.add_new_task_dialog_title)
            .setPositiveButton(R.string.add_new_task_dialog_positive, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    addTask();
                }
            })
            .create();
}
}

TaskLab.java this is a singleton class TaskLab.java,这是一个单例类

public class TaskLab {

private static TaskLab sTaskLab;

private Context mContext;
private SQLiteDatabase mDatabase;

private TaskLab(Context context){
    mContext = context.getApplicationContext();
    mDatabase = new TaskBaseHelper(mContext).getWritableDatabase();
}

public static TaskLab get(Context context) {
    if(sTaskLab == null) {
        sTaskLab = new TaskLab(context);
    }

    return sTaskLab;
}


public List<Task> getTaskList(){

    List<Task> taskList = new ArrayList<Task>();
    TaskCursorWrapper cursor = queryTasks(null, null);

    // If there is something in the table query it
    try {
        cursor.moveToFirst();
        while(!cursor.isAfterLast()) {
            Task task = cursor.getTask();
            taskList.add(task);
            cursor.moveToNext();
        }
    } finally {
        cursor.close();
    }
    return taskList;
}

public void addTask(Task task) {
    ContentValues values = getContentValues(task);
    mDatabase.insert(TaskTable.NAME, null, values);
}

public void updateTask(Task task) {
    ContentValues values = getContentValues(task);
    String uuidString = task.getId().toString();
    mDatabase.update(TaskTable.NAME,values, TaskTable.Cols.UUID + " = ?", new String[] {uuidString});
}

public Task getTask(UUID id){

    TaskCursorWrapper cursor = queryTasks(TaskTable.Cols.UUID + " = ?",
            new String[] {id.toString()});

    try {
        if(cursor.getCount() == 0) {
            return null;
        }

        cursor.moveToFirst();
        return cursor.getTask();
    } finally {
        cursor.close();
    }
}

private static ContentValues getContentValues(Task task) {
    ContentValues values = new ContentValues();

    values.put(TaskTable.Cols.UUID, task.getId().toString());
    values.put(TaskTable.Cols.TITLE, task.getTitle());
    values.put(TaskTable.Cols.SOLVED, task.isSolved());

    return values;
}

private TaskCursorWrapper queryTasks(String whereClause, String[] whereArgs) {
    Cursor cursor = mDatabase.query(TaskTable.NAME,
            null,
            whereClause,
            whereArgs,
            null,
            null,
            null);
    return new TaskCursorWrapper(cursor);
}

}

必须从头开始每次都要在updateUI中重新创建适配器

Try it like this and see. 像这样尝试,看看。 In your onCreateView() of fragment before updateUI() add below line of code. 在updateUI()之前的片段的onCreateView()中,添加以下代码行。

Note: Create taskList as global variable. 注意:创建taskList作为全局变量。

mRecyclerView = view.findViewById(R.id.the_task_list);
mAdapter = new TaskAdapter(taskList);
mRecyclerView.setAdapter(mAdapter);

updateUI();

After that create your updateUI() method as below 之后,如下所示创建您的updateUI()方法

public void updateUI() {
    taskList.clear;
    taskList = TaskLab.get(getActivity()).getTaskList();
    mAdapter.notifyDataSetChanged();
}

Update: 更新:

As per your updated question, declare one global variable in ListFragment as 根据您更新的问题,在ListFragment中声明一个全局变量为

public static ListFragment listFragment;

In your onCreate method of ListFragment after inflating view add below line of code. 在放大视图后在ListFragment的onCreate方法中,添加以下代码行。

// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_list, container, false);

listFragment = this; 

Then change your addTask method in AddTaskFragment as below. 然后如下所示在AddTaskFragment中更改您的addTask方法。

private void addTask() {
    if(!mTaskTitle.getText().toString().equals("")) {
        Task task = new Task();
        task.setTitle(mTaskTitle.getText().toString());

        TaskLab.get(getActivity()).addTask(task);

        //import listfragment from your ListFragment
        listFragment.updateUI();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的片段不能显示来自 recyclerview 的数据? - Why ain't my fragment cannot display data from recyclerview? 如何在我的 RecyclerView 中显示来自 firebase 的子数据? - How do I display child of child's data from firebase in my RecyclerView? 为什么我的应用程序因 RecyclerView 而崩溃? - Why is my app Crashing with RecyclerView? 如何使用JSON从远程数据库检索数据并显示在android应用程序xml文件中? - How do i retrieve the data using JSON from the Remote Database and display in my android app xml file? 如何在 android studio 中使用 recyclerview 显示我的数据库? - How do i display my database using recyclerview in android studio? SQLite数据未在我的RecyclerView中删除 - SQLite data not getting deleted in my RecyclerView 从SQLite数据库获取数据并显示在recyclerview中 - getting data from a SQLite database and display in recyclerview 如何将从doInBackground()获得的数据应用于我的RecyclerView? - How do I go about applying data I get from doInBackground() to apply to my RecyclerView? 我的android应用程序的数据库SQLite的排序结果有问题 - I have a Problem with the sorting result of the database SQLite of my android app 我将名称存储在mysql中,如何在android应用中显示该信息 - I have names stored in mysql how do I display that information in my android app
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM