在 Android 中以 ArrayAdapter 中的视图为目标
Targeting a View within an ArrayAdapter in Android
我不确定我问的这个问题是否正确,因为我根本找不到任何相关信息。
我想知道是否可以从我的 Activity 中通过 ArrayAdapter 添加的视图 (ImageView) 定位。
我的 Activity 从服务器接收到 JSON,关于用户的配置文件。我将该信息显示到 ArrayAdapter 中。在 ArrayAdapter 中,我有一个 ImageView,它调用一种方法来更改用户的个人资料图像。用户选择 his/her 图片,最后 ImageView 随之改变。
问题是我实际上无法定位 ImageView。下面是我的代码:
简介Activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_profile);
userAdapter = new UserAdapter(this, new ArrayList<UserModel>());
listView = (ListView) findViewById(R.id.myProfile_header);
listView.setAdapter(userAdapter);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
(new FetchUserTask()).execute(Constants.HOST + token.getAccessToken());
image = (ImageView) findViewById(R.id.myProfile_avatar);
avatarChange = (LinearLayout) findViewById(R.id.myProfile_avatar_change);
}
public String uriToPath(Uri uri) {
String res = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, proj, null, null, null);
if(cursor.moveToFirst()){
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && (requestCode == SELECT_IMAGE_CODE || requestCode == CAMERA_IMAGE)) {
Uri uri = Uri.parse("file://"+uriToPath(data.getData()));
Picasso.with(this).load(uri).into(image);
}
/*...*/
}
配置文件适配器:
/*...*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.profile_header, null);
}
final ViewHolder viewHolder = new ViewHolder(v);
v.setTag(viewHolder);
final UserModel model = user.get(position);
String userAvatar = model.getPhoto();
viewHolder.name.setText(model.getUsername());
viewHolder.email.setText(model.getEmail());
viewHolder.phone.setText(model.getPhone_number());
if (userAvatar != null && !userAvatar.isEmpty()) {
//System.out.println(userAvatar);
Picasso.with(getContext()).load(HOST+userAvatar).into(viewHolder.avatar);
}
viewHolder.avatarChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectImageFromGallery();
}
});
return v;
}
public void selectImageFromGallery() {
final CharSequence[] items = { "Take Photo", "Choose from Library",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Take Photo")) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment
.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
((Activity) context).startActivityForResult(intent, CAMERA_IMAGE);
} else if (items[item].equals("Choose from Library")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
((Activity) context).startActivityForResult(
Intent.createChooser(intent, "Select File"),
SELECT_IMAGE_CODE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
/*...*/
我必须感谢 John P. and Guardanis 提供了关于为什么我无法定位 ListView 的内部 child 的主要线索。它帮助改变了我思考问题本身的方式。我以为问题出在 Adapter 上,但在他们的建议下变得很清楚,问题出在 Activity.
代码更改本质上是:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && (requestCode == SELECT_IMAGE_CODE || requestCode == CAMERA_IMAGE)) {
Uri imageUri = data.getData();
View child = header.getChildAt(0);
View image = child.findViewById(R.id.myProfile_avatar);
Resources resources = getResources();
ImageView imageX = (ImageView) image;
imageX.setImageDrawable(resources.getDrawable(R.drawable.blank));
Picasso.with(this).load(imageUri).into(imageX);
profileAdapter.notifyDataSetChanged();
}
}
有了这个,我可以使用 ListView.getChild(int)
访问我需要的视图,其中 "header" 是我的 ListView,0 是我的整数。然后将 View
(child) 声明为 ImageView
,我能够按照我想要的方式操作它的属性。在我的适配器上完成 notifyDataStateChanged()
以确保会发生更改。
旁注:我需要调用 getResources()
来改变我的 ImageView
。不太清楚那是什么,我会在以后研究它。
我不确定我问的这个问题是否正确,因为我根本找不到任何相关信息。
我想知道是否可以从我的 Activity 中通过 ArrayAdapter 添加的视图 (ImageView) 定位。
我的 Activity 从服务器接收到 JSON,关于用户的配置文件。我将该信息显示到 ArrayAdapter 中。在 ArrayAdapter 中,我有一个 ImageView,它调用一种方法来更改用户的个人资料图像。用户选择 his/her 图片,最后 ImageView 随之改变。
问题是我实际上无法定位 ImageView。下面是我的代码:
简介Activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_profile);
userAdapter = new UserAdapter(this, new ArrayList<UserModel>());
listView = (ListView) findViewById(R.id.myProfile_header);
listView.setAdapter(userAdapter);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
(new FetchUserTask()).execute(Constants.HOST + token.getAccessToken());
image = (ImageView) findViewById(R.id.myProfile_avatar);
avatarChange = (LinearLayout) findViewById(R.id.myProfile_avatar_change);
}
public String uriToPath(Uri uri) {
String res = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, proj, null, null, null);
if(cursor.moveToFirst()){
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && (requestCode == SELECT_IMAGE_CODE || requestCode == CAMERA_IMAGE)) {
Uri uri = Uri.parse("file://"+uriToPath(data.getData()));
Picasso.with(this).load(uri).into(image);
}
/*...*/
}
配置文件适配器:
/*...*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.profile_header, null);
}
final ViewHolder viewHolder = new ViewHolder(v);
v.setTag(viewHolder);
final UserModel model = user.get(position);
String userAvatar = model.getPhoto();
viewHolder.name.setText(model.getUsername());
viewHolder.email.setText(model.getEmail());
viewHolder.phone.setText(model.getPhone_number());
if (userAvatar != null && !userAvatar.isEmpty()) {
//System.out.println(userAvatar);
Picasso.with(getContext()).load(HOST+userAvatar).into(viewHolder.avatar);
}
viewHolder.avatarChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectImageFromGallery();
}
});
return v;
}
public void selectImageFromGallery() {
final CharSequence[] items = { "Take Photo", "Choose from Library",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Take Photo")) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment
.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
((Activity) context).startActivityForResult(intent, CAMERA_IMAGE);
} else if (items[item].equals("Choose from Library")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
((Activity) context).startActivityForResult(
Intent.createChooser(intent, "Select File"),
SELECT_IMAGE_CODE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
/*...*/
我必须感谢 John P. and Guardanis 提供了关于为什么我无法定位 ListView 的内部 child 的主要线索。它帮助改变了我思考问题本身的方式。我以为问题出在 Adapter 上,但在他们的建议下变得很清楚,问题出在 Activity.
代码更改本质上是:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && (requestCode == SELECT_IMAGE_CODE || requestCode == CAMERA_IMAGE)) {
Uri imageUri = data.getData();
View child = header.getChildAt(0);
View image = child.findViewById(R.id.myProfile_avatar);
Resources resources = getResources();
ImageView imageX = (ImageView) image;
imageX.setImageDrawable(resources.getDrawable(R.drawable.blank));
Picasso.with(this).load(imageUri).into(imageX);
profileAdapter.notifyDataSetChanged();
}
}
有了这个,我可以使用 ListView.getChild(int)
访问我需要的视图,其中 "header" 是我的 ListView,0 是我的整数。然后将 View
(child) 声明为 ImageView
,我能够按照我想要的方式操作它的属性。在我的适配器上完成 notifyDataStateChanged()
以确保会发生更改。
旁注:我需要调用 getResources()
来改变我的 ImageView
。不太清楚那是什么,我会在以后研究它。