将图库中的图片路径保存到Room数据库并在Recycler列表中显示

6
有一组学生名单,每一行都显示了一张图片、姓名和编号。我创建了一个Room数据库,并使用这个指南成功地将“姓名”和“编号”列填充到列表中。(此处链接略) 当用户打开AddNewStudentActivity时,需要从相册选择一张照片,并在两个editText中填写姓名和编号,点击“保存”并将学生保存到studentDatabase中。
在列表中应该显示这个图像以及那两个文本(姓名和编号)。
我不知道怎么做,只是认为这个过程应该像“设置一个打开相册的intent,我们可以选择一张图片,并把它的路径存储在数据库中,然后从数据库中显示到列表中”。但我不知道如何编码。有关此问题的教程都使用SQLITE,而不是Room,我对整个数据库主题很陌生。
- 谢谢
NewStudentActivity.java
public class NewStudentActivity extends AppCompatActivity {

    public static final String EXTRA_REPLY = "com.example.android.studentlistsql.REPLY";

    private EditText mNameWordView;
    private EditText mNumWordView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_student);
        mNameWordView = findViewById(R.id.name_word);
        mNumWordView = findViewById(R.id.num_word);

        final Button button = findViewById(R.id.button_save);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent replyIntent = new Intent();
                if (TextUtils.isEmpty(mNameWordView.getText())) {
                    setResult(RESULT_CANCELED, replyIntent);
                } else {
                    String word = mNameWordView.getText().toString();
                    replyIntent.putExtra(EXTRA_REPLY, word);
                    setResult(RESULT_OK, replyIntent);
                }
                if (TextUtils.isEmpty(mNumWordView.getText())) {
                    setResult(RESULT_CANCELED, replyIntent);
                } else {
                    String word = mNumWordView.getText().toString();
                    replyIntent.putExtra(EXTRA_REPLY, word);
                    setResult(RESULT_OK, replyIntent);
                }
                finish();
            }
        });

    }
}

StudentListAdapter.java

public class StudentListAdapter extends RecyclerView.Adapter<StudentListAdapter.WordViewHolder> {

    class WordViewHolder extends RecyclerView.ViewHolder {
        private final TextView nameItemView;
        private final TextView numberItemView;

        private WordViewHolder(View itemView) {
            super(itemView);
            nameItemView = itemView.findViewById(R.id.nameTextView);
            numberItemView = itemView.findViewById(R.id.numberTextView);
        }
    }

    private final LayoutInflater mInflater;
    private List<Student> mStudents; // Cached copy of words

    StudentListAdapter(Context context) { mInflater = LayoutInflater.from(context); }

    @Override
    public WordViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = mInflater.inflate(R.layout.recyclerview_item, parent, false);
        return new WordViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(WordViewHolder holder, int position) {
        if (mStudents != null) {
            Student current = mStudents.get(position);
            holder.nameItemView.setText(current.getStudentName());
            holder.numberItemView.setText(current.getStudentNumber());
        } else {
            // Covers the case of data not being ready yet.
            holder.nameItemView.setText("No Word");
        }
    }

    void setStudents(List<Student> words){
        mStudents = words;
        notifyDataSetChanged();
    }

    // getItemCount() is called many times, and when it is first called,
    // mWords has not been updated (means initially, it's null, and we can't return null).
    @Override
    public int getItemCount() {
        if (mStudents != null)
            return mStudents.size();
        else return 0;
    }
}

我意识到我回答了问题,但没有谈论Room,你关于Room的问题确切是关于插入还是查询?或者其他什么。 - Suleyman
2个回答

5
坦白说,这个过程和 Room 并没有太大区别。如你所说,从图库选择照片需要使用一个意图(intent):
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "select a picture"), YOUR_IMAGE_CODE);

然后你需要在onActivityResult中处理这个情况:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == YOUR_IMAGE_CODE) {
        if(resultCode == RESULT_OK)
            Uri selectedImageUri = data.getData();
    }
}

所以selectedImageUri是您保存在数据库中的信息。在您的实体类Student.java中,您可以将mStudentPic更改为String,这样当您插入Uri时,您可以使用一个方法:

selectedImageUri.toString();

当您想将其转换回Uri时:

Uri uri = Uri.parse(yourUriAsString);

我假设您已经知道如何插入和查询数据库中的值。
然后在您的onBindViewHolder中,您可以使用GlidePicasso,或任何其他库来加载图像,例如使用Glide:
Glide.with(context)
.load(new File(uri.getPath()))
.into(imageView);

onBindViewHolder中,我应该把什么作为Glide.with(context)的“context”传递?我的onBindViewHolder签名是public void onBindViewHolder(@NonNull ProductViewHolder holder, int position) - zodiac645
@zodiac645 这是调用回收视图的活动/片段的上下文,通常会在回收视图的构造函数中传递它。 - Suleyman
我试图在片段的适配器类下管理它。onBindViewHolder()方法在该适配器中。 - zodiac645
请问如何在 Fragment Adapter 中使用 Glide 库? - zodiac645
@zodiac645,你无法在onBindViewHolder的参数中获取上下文,你需要从活动或片段中传递它,请检查你链接的问题的第一个答案。 - Suleyman
显示剩余16条评论

2
此外,我正在使用与SQLite相同的函数,只存储图像路径,并从SQLite获取该路径,然后使用图像URI加载图像。
holder.imgUserPhoto.setImageURI(Uri.parse(new File(contactModel.getContactPhoto()).toString()));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接