1

我是一个安卓菜鸟。

我的主要活动包含一个回收视图,其中列出了用户/学生预订的所有课程。数据来自 SQLite DB。当用户点击其中一个课程时,一个新活动 (LessonInfo) 会显示其详细信息,并且——只有其中一个处于特定状态(“prenotato”,即已预订)——用户可以通过按下两个不同的按钮来更改其状态。

在用户按下这些按钮之一后,我正在尝试更新 MainActivity 中的回收站视图。目前,视图会在每次 onResume 和每次提取数据库中的所有数据时更新。

主活动-->课程信息-->主活动已更新

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

LessonsRecyclerAdapter

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()(DEPRECATED) 和notifyItemChanged().

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

为了让用户看到 LessonInfo 活动中的变化(不会自动返回 MainActivity),我只是isLessonUpdated在函数中使用了一个布尔值作为标志onBackPressed():当用户返回上一个活动时,当且仅当他已经改变了课程的状态,我设置了Intent的结果。

最后,我用 替换了不推荐使用的函数registerForActivityResult()registerForActivityResult相应地更改了主要活动中的 onItemClick。

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

新的 MainActivity

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

1 回答 1

0

对于您的第一个问题“仅在用户更改一堂课的状态时获取数据”,您可以使用registerForActivityResult()MainActivity 中的有任何变化。查看文档以获取更多详细信息。

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

于 2022-01-31T10:23:23.833 回答