Передать данные из дочерней активности в переработчик в предыдущей активности

Я андроид нуб.

Моя основная деятельность содержит представление переработчика, в котором перечислены все уроки, забронированные пользователем/учащимся. Данные поступают из базы данных SQLite. Когда пользователь нажимает на один из этих уроков, новое занятие (LessonInfo) показывает его детали и — только если оно находится в определенном статусе («prenotato», т. е. забронировано) — пользователь может изменить его статус, нажав две разные кнопки.

Я пытаюсь обновить представление ресайклера внутри моей MainActivity после того, как пользователь нажмет одну из этих кнопок. На данный момент представление обновляется при каждом onResume и каждый раз, когда отображаются все данные из БД.

Основное занятие --> LessonInfo -->Основное занятие обновлено

Я хотел бы 1) получать данные только в том случае, если пользователь меняет статус одного урока, и 2) обновлять только владельца этого конкретного урока, используя его позицию. Я пытался несколько раз, но я заблокирован...

Большое спасибо

Основная деятельность

      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();
}

УрокиRecyclerAdapter

      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();
        }
    });
}

ОБНОВЛЕНИЕ - РЕШЕНО

Благодаря Таранмиту Сингху я смог найти способ достичь своей цели.

Сначала я попробовал простейший подход, используя startActivityForResult() (УСТАРЕЛО) и notifyItemChanged().

Затем я заметил, что мне пришлось внести некоторые изменения в onClickListeners внутри LessonsInfo: вместо воссоздания активности я теперь вспоминаю функцию ( switchView()) Ведьма просто изменяет внешний вид.

Чтобы пользователь мог видеть изменения внутри активности LessonInfo (без автоматического возврата к MainActivity), я просто использовал логическое значение isLessonUpdatedкак флаг внутри функции onBackPressed(): когда пользователь возвращается к предыдущему действию, если и только если он изменил статус урока, я устанавливаю результат Intent.

Наконец, я заменил устаревшую функцию registerForActivityResult()с участием registerForActivityResult, соответствующим образом изменив onItemClick внутри основного действия.

Это код, который я придумал. Никаких соответствующих изменений не было применено к LessonRecyclerAdapter.java. Не стесняйтесь предлагать улучшения.

Новая основная активность

      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();
}

1 ответ

Для вашего первого вопроса «получить данные только в том случае, если пользователь изменит статус одного урока» вы можете вызвать активность LessonInfo, используя registerForActivityResult()из MainActivity таким образом вы можете передать результат, который может быть логическим или любым флагом, который сообщает MainActivity, есть ли какие-либо изменения. Проверьте эти документы для получения более подробной информации.

Для вашего второго вопроса «обновить только владельца этого конкретного урока, используя его позицию», вам нужно использовать notifyItemChanged()метод адаптера представления ресайклера, чтобы обновить пользовательский интерфейс только 1 элемента и оставить остальные неизменными. Проверьте эти документы для обновления одного элемента.

Другие вопросы по тегам