将来自 child activity 的数据传递到之前的 activity 中回收

Passind data from child activity to recycler in previous activity

我是一个android菜鸟。

My Main Activity 包含一个回收器视图,其中列出了 user/student 预订的所有课程。数据来自 SQLite 数据库。 当用户点击其中一节课时,一个新的 activity (LessonInfo) 会显示它的详细信息,并且只有它处于某种状态(“prenotato”,即已预订)——用户可以通过按两个不同的按钮。

我正在尝试在用户按下其中一个按钮后更新我的 MainActivity 中的回收器视图。目前,视图在每次 onResume 和每次从数据库中获取所有数据时都会更新。

Main Activity --> LessonInfo -->Main Activity Updated

我希望 1) 仅在用户更改一节课的状态时获取数据,以及 2) 使用其位置仅更新该特定课的持有者。 试了好几次都被锁了...

非常感谢

主要Activity

public class MainActivity extends AppCompatActivity implements LessonsRecyclerAdapter.ClickInterface{
private TextView textViewName;
private RecyclerView recyclerViewLessons;
private ArrayList<Lezioni> lezioni;
private DatabaseHelper db;
private Studenti studente;

private LessonsRecyclerAdapter lessonsRecyclerAdapter;

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

    initViews();
    initObjects();
}

private void initViews() {
    textViewName = findViewById(R.id.textViewName);
    recyclerViewLessons = (RecyclerView) findViewById(R.id.recyclerViewLessons);
}

private void initObjects() {
    lezioni = new ArrayList<>();
    lessonsRecyclerAdapter = new LessonsRecyclerAdapter(lezioni, this, this);
    db = new DatabaseHelper(MainActivity.this);

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerViewLessons.setLayoutManager(mLayoutManager);
    recyclerViewLessons.setHasFixedSize(true);
    recyclerViewLessons.setAdapter(lessonsRecyclerAdapter);

    Gson gson = new Gson();
    studente = gson.fromJson(getIntent().getStringExtra("studente"), Studenti.class);
    textViewName.setText(studente.getNome_st());

    getLessonsFromSQLite();
}

@SuppressLint("NotifyDataSetChanged")
private void getLessonsFromSQLite() {
    Executor executor = Executors.newSingleThreadExecutor();
    Handler handler = new Handler(Looper.getMainLooper());

    executor.execute(() -> {
        lezioni.clear();
        lezioni.addAll(db.readLezioni(studente.getMatricola()));
        handler.post(() -> lessonsRecyclerAdapter.notifyDataSetChanged());
    });
}

public void onItemClick(int positionOfLesson){
    Intent intent = new Intent(this, LessonInfo.class);
    intent.putExtra("id_lezione", lezioni.get(positionOfLesson).getId_lezione());
    startActivity(intent);
}

@Override
protected void onResume() {
    super.onResume();
    getLessonsFromSQLite();
}

课程回收器适配器

public class LessonsRecyclerAdapter extends RecyclerView.Adapter<LessonsRecyclerAdapter.LessonsViewHolder> {

ArrayList<Lezioni> lezioni;
Context context;
ClickInterface clickInterface;

public LessonsRecyclerAdapter(ArrayList<Lezioni> lezioni, Context context, ClickInterface clickInterface) {
    this.lezioni = lezioni;
    this.context = context;
    this.clickInterface = clickInterface;
}

@NonNull
@Override
public LessonsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(context).inflate(R.layout.item_lessons_recycler, parent, false);
    return new LessonsViewHolder(itemView);
}

@Override
public void onBindViewHolder(LessonsViewHolder holder, int position) {
    DatabaseHelper db = new DatabaseHelper(context);
    Materie materia = db.getMateriaFromDB(db.getDocenteFromDB(lezioni.get(position).getId_docente()).getId_materia());
    holder.textViewInsegnamento.setText(materia.getNome_materia());                           
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    holder.textViewData.setText(lezioni.get(position).getParsedData().toLocalDate().format(formatter)); 
    holder.textViewStato.setText(lezioni.get(position).getStato_lezione()); if(lezioni.get(position).getStato_lezione().equals("disdetta")){
        holder.textViewStato.setTextColor(ContextCompat.getColor(context, R.color.yellow));
    }else if(lezioni.get(position).getStato_lezione().equals("frequentata")){
        holder.textViewStato.setTextColor(ContextCompat.getColor(context, R.color.green));
    }else{
        holder.textViewStato.setTextColor(ContextCompat.getColor(context, R.color.color_text));
    }

}

@Override
public int getItemCount() {
    Log.v(LessonsRecyclerAdapter.class.getSimpleName(),""+lezioni.size());
    return lezioni.size();
}

public  class LessonsViewHolder extends RecyclerView.ViewHolder {
    AppCompatTextView textViewInsegnamento;
    AppCompatTextView textViewData;
    AppCompatTextView textViewStato;

    public LessonsViewHolder(View view) {
        super(view);
        textViewInsegnamento = (AppCompatTextView) view.findViewById(R.id.textViewInsegnamento);
        textViewData = (AppCompatTextView) view.findViewById(R.id.textViewData);
        textViewStato = (AppCompatTextView) view.findViewById(R.id.textViewStato);

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                clickInterface.onItemClick(getAdapterPosition());
            }
        });
    }
}

public interface ClickInterface{
    void onItemClick(int positionOfLesson);
}

课程信息

public class LessonInfo extends AppCompatActivity {
private TextView txtGiorno, txtOra, txtMateria, txtDocente;
private DatabaseHelper db;
private ConstraintLayout lessonContainer;
private Lezioni lezione;
private Docenti docente;
private Materie materia;
private LinearLayout interactiveButtons;
private Button btnCancel, btnConfirm;

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

    initViews();
    initObjects();

    txtGiorno.setText(lezione.getData().split(" ")[0]);
    txtOra.setText(String.format(getString(R.string.from_to_time), lezione.getFromTime(), lezione.getToTime()));
    txtMateria.setText(materia.getNome_materia());
    txtDocente.setText(docente.getNome_doc());

    switchView();
}

private void initViews() {
    lessonContainer = findViewById(R.id.lessonContainer);
    txtGiorno = findViewById(R.id.txtGiorno);
    txtOra = findViewById(R.id.txtOra);
    txtMateria = findViewById(R.id.txtMateria);
    txtDocente = findViewById(R.id.txtDocente);
    interactiveButtons = findViewById(R.id.interactiveButtons);
}

private void switchView(){
    GradientDrawable drawable = (GradientDrawable) lessonContainer.getBackground();
    if(lezione.getStato_lezione().equals("disdetta")){
        TextView txtStatus = findViewById(R.id.txtStatus);
        drawable.setStroke(4, ContextCompat.getColor(this,R.color.primary));
        txtStatus.setVisibility(View.VISIBLE);
        interactiveButtons.setVisibility(View.GONE);
    }else if(lezione.getStato_lezione().equals("frequentata")){
        LinearLayout lessonFrequented = findViewById(R.id.lessonFrequented);
        drawable.setStroke(4, ContextCompat.getColor(this,R.color.green));
        lessonFrequented.setVisibility(View.VISIBLE);
        interactiveButtons.setVisibility(View.GONE);
    }else{
        btnCancel = findViewById(R.id.btnCancel);
        btnConfirm = findViewById(R.id.btnConfirm);
        interactiveButtons.setVisibility(View.VISIBLE);
        drawable.setStroke(4, ContextCompat.getColor(this,R.color.gray));
        setOnClickListeners();
    }
}

private void initObjects() {
    db = new DatabaseHelper(getApplicationContext());
    lezione = db.getLezioneFromDB(getIntent().getIntExtra("id_lezione", 0));
    docente = db.getDocenteFromDB(lezione.getId_docente());
    materia = db.getMateriaFromDB(docente.getId_materia());
}


private void setOnClickListeners(){
    btnCancel.setOnClickListener(view -> {
        lezione.setStato_lezione("disdetta");
        if(db.updateStatoLezione(lezione)){
            LessonInfo.this.recreate();
        }else{
            Toast.makeText(LessonInfo.this, "ERROR", Toast.LENGTH_SHORT).show();
        }
    });

    btnConfirm.setOnClickListener(view -> {
        lezione.setStato_lezione("frequentata");
        if(db.updateStatoLezione(lezione)){
            LessonInfo.this.recreate();
        }else{
            Toast.makeText(LessonInfo.this, "ERROR", Toast.LENGTH_SHORT).show();
        }
    });
}

更新 - 已解决

感谢 Taranmeet Singh,我找到了实现目标的方法。

我首先尝试了使用 startActivityForResult()(已弃用)和 notifyItemChanged() 的最简单方法。

我注意到我必须对 LessonsInfo 中的 onClickListeners 进行一些更改:而不是重新创建 activity 我现在回忆起一个函数 (switchView()) 只是修改外观.

为了让用户看到LessonInfoactivity里面的变化(不会自动回到MainActivity),我只是用了一个布尔值isLessonUpdated作为标志在函数 onBackPressed() 中:随着用户返回到之前的 activity,当且仅当他更改了课程状态时,我才设置 Intent 的结果。

最后,我将已弃用的函数 registerForActivityResult() 替换为 registerForActivityResult,相应地更改了主函数 activity 中的 onItemClick。

这是我想出的代码。没有对 LessonRecyclerAdapter.java 应用任何相关更改。欢迎提出改进建议。

新主线Activity

public class MainActivity extends AppCompatActivity implements LessonsRecyclerAdapter.ClickInterface{
private TextView textViewName;
private RecyclerView recyclerViewLessons;
private ArrayList<Lezioni> lezioni;
private DatabaseHelper db;
private Studenti studente;
int positionClicked;
int idClicked;
private LessonsRecyclerAdapter lessonsRecyclerAdapter;

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

    initViews();
    initObjects();
}

private void initViews() {
    textViewName = findViewById(R.id.textViewName);
    recyclerViewLessons = findViewById(R.id.recyclerViewLessons);
}

private void initObjects() {
    lezioni = new ArrayList<>();
    lessonsRecyclerAdapter = new LessonsRecyclerAdapter(lezioni, this, this);
    db = new DatabaseHelper(MainActivity.this);

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerViewLessons.setLayoutManager(mLayoutManager);
    recyclerViewLessons.setHasFixedSize(true);
    recyclerViewLessons.setAdapter(lessonsRecyclerAdapter);

    Gson gson = new Gson();
    studente = gson.fromJson(getIntent().getStringExtra("studente"), Studenti.class);
    textViewName.setText(studente.getNome_st());

    getLessonsFromSQLite();
}

@SuppressLint("NotifyDataSetChanged")
private void getLessonsFromSQLite() {
    Executor executor = Executors.newSingleThreadExecutor();
    Handler handler = new Handler(Looper.getMainLooper());

    executor.execute(() -> {
        lezioni.clear();
        lezioni.addAll(db.readLezioni(studente.getMatricola()));
        handler.post(() -> lessonsRecyclerAdapter.notifyDataSetChanged());
    });
}

public void onItemClick(int positionOfLesson){
    idClicked = lezioni.get(positionOfLesson).getId_lezione();
    positionClicked = positionOfLesson;
    Intent intent = new Intent(this, LessonInfo.class);
    intent.putExtra("id_lezione", lezioni.get(positionClicked).getId_lezione());
    LessonResultLauncher.launch(intent);
}

ActivityResultLauncher<Intent> LessonResultLauncher = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            if (result.getResultCode() == Activity.RESULT_OK) {
                lezioni.set(positionClicked, db.getLezioneFromDB(idClicked));
                lessonsRecyclerAdapter.notifyItemChanged(positionClicked);
            }
        }
    });

新课程信息

public class LessonInfo extends AppCompatActivity {
private TextView txtGiorno, txtOra, txtMateria, txtDocente;
private DatabaseHelper db;
private ConstraintLayout lessonContainer;
private Lezioni lezione;
private Docenti docente;
private Materie materia;
private LinearLayout interactiveButtons;
private Button btnCancel, btnConfirm;
private Boolean isLessonUpdated = false;

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

    initViews();
    initObjects();

    txtGiorno.setText(lezione.getData().split(" ")[0]);
    txtOra.setText(String.format(getString(R.string.from_to_time), lezione.getFromTime(), lezione.getToTime()));
    txtMateria.setText(materia.getNome_materia());
    txtDocente.setText(docente.getNome_doc());

    switchView();
}

private void initViews() {
    lessonContainer = findViewById(R.id.lessonContainer);
    txtGiorno = findViewById(R.id.txtGiorno);
    txtOra = findViewById(R.id.txtOra);
    txtMateria = findViewById(R.id.txtMateria);
    txtDocente = findViewById(R.id.txtDocente);
    interactiveButtons = findViewById(R.id.interactiveButtons);
}

private void switchView(){
    GradientDrawable drawable = (GradientDrawable) lessonContainer.getBackground();
    if(lezione.getStato_lezione().equals("disdetta")){
        TextView txtStatus = findViewById(R.id.txtStatus);
        drawable.setStroke(4, ContextCompat.getColor(this,R.color.primary));
        txtStatus.setVisibility(View.VISIBLE);
        interactiveButtons.setVisibility(View.GONE);
    }else if(lezione.getStato_lezione().equals("frequentata")){
        LinearLayout lessonFrequented = findViewById(R.id.lessonFrequented);
        drawable.setStroke(4, ContextCompat.getColor(this,R.color.green));
        lessonFrequented.setVisibility(View.VISIBLE);
        interactiveButtons.setVisibility(View.GONE);
    }else{
        btnCancel = findViewById(R.id.btnCancel);
        btnConfirm = findViewById(R.id.btnConfirm);
        interactiveButtons.setVisibility(View.VISIBLE);
        drawable.setStroke(4, ContextCompat.getColor(this,R.color.gray));
        setOnClickListeners();
    }
}

private void initObjects() {
    db = new DatabaseHelper(getApplicationContext());
    lezione = db.getLezioneFromDB(getIntent().getIntExtra("id_lezione", 0));
    docente = db.getDocenteFromDB(lezione.getId_docente());
    materia = db.getMateriaFromDB(docente.getId_materia());
}


private void setOnClickListeners(){
    btnCancel.setOnClickListener(view -> {
        lezione.setStato_lezione("disdetta");
        if(db.updateStatoLezione(lezione)){
            isLessonUpdated = true;
            switchView();
        }else{
            Toast.makeText(LessonInfo.this, "ERROR", Toast.LENGTH_SHORT).show();
        }
    });

    btnConfirm.setOnClickListener(view -> {
        lezione.setStato_lezione("frequentata");
        if(db.updateStatoLezione(lezione)){
            isLessonUpdated = true;
            switchView();
        }else{
            Toast.makeText(LessonInfo.this, "ERROR", Toast.LENGTH_SHORT).show();
        }
    });
}

@Override
public void onBackPressed() {
    Intent intent = new Intent();
    if(isLessonUpdated){
        Log.d("FLAG", "TRUE");
        setResult(RESULT_OK, intent);
    }
    finish();
}

对于您的第一个问题“仅当用户更改一节课的状态时才获取数据”,您可以使用 MainActivity 中的 registerForActivityResult() 调用 LessonInfo Activity您可以传回一个结果,该结果可以是布尔值或任何告诉 MainActivity 是否有任何更改的标志。查看 this 文档了解更多详情。

对于您的第二个问题“仅更新该特定课程的持有者,使用其位置”,您需要使用回收器视图适配器的 notifyItemChanged() 方法来仅更新 1 项的 UI让其他人保持不变。检查 this 文档以更新一项。