[英]Android Listview load image from String click
我有一个项目列表,单击列表后,新活动将打开详细信息。 问题是我无法实现 - 单击详细活动中的特定字符串后加载图像。 例如,在 MainActivity 中,有:
String one[] = {"dog", "cat", "horse", "snail"};
String two[] = {"aaa", "bbb", "ccc", "ddd"};
String three[] = {"111", "**222**", "333", "**222**"};
打开应用程序,单击第二个列表项(猫)并打开包含我需要的详细信息的新活动(猫的所有字符串),在这种情况下,单击“字符串三”后 - 如果字符串为 222,则打开图像(drawable/222. jpg),在这种情况下是“猫”和“蜗牛”。 然后点击“333”显示图像333.jpg...
如果可能的话,最好用返回按钮打开图像,到 go 返回详细活动。
简化的 MainActivity:
String one[] = {"dog", "cat", "horse", "snail"};
String two[] = {"aaa", "bbb", "ccc", "ddd"};
String three[] = {"111", "222", "333", "222"};
List<ItemsModel> itemsModelList = new ArrayList<>();
ListView listView;
CustomAdapter customAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listview);
for(int i = 0;i < one.length;i++){
ItemsModel itemsModel = new ItemsModel(one[i],two[i],three[i]);
itemsModelList.add(itemsModel);
}
customAdapter = new CustomAdapter(itemsModelList,this);
listView.setAdapter(customAdapter);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if(id == R.id.searchView){
return true;
}
return super.onOptionsItemSelected(item);
}
public class CustomAdapter extends BaseAdapter implements Filterable {
private List<ItemsModel> itemsModelsl;
private List<ItemsModel> itemsModelListFiltered;
private Context context;
public CustomAdapter(List<ItemsModel> itemsModelsl, Context context) {
this.itemsModelsl = itemsModelsl;
this.itemsModelListFiltered = itemsModelsl;
this.context = context;
}
@Override
public int getCount() {
return itemsModelListFiltered.size();
}
@Override
public Object getItem(int position) {
return itemsModelListFiltered.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = getLayoutInflater().inflate(R.layout.row_items,null);
TextView one = view.findViewById(R.id.one);
TextView two = view.findViewById(R.id.two);
one.setText(itemsModelListFiltered.get(position).getone());
two.setText(itemsModelListFiltered.get(position).gettwo());
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("main activity","item clicked");
startActivity(new Intent(MainActivity.this, ItemsActivity.class).putExtra("items",itemsModelListFiltered.get(position)));
}
});
return view;
}
//// 项目模型:
public class ItemsModel implements Serializable {
private String one;
private String two;
private String three;
public ItemsModel(String one, String two, String three) {
this.one = one;
this.two = two;
this.three = three;
}
public String getone() {
return one;
}
public void setone(String one) {
this.one = one;
}
public String gettwo() {return two; }
public void settwo(String two) { this.two = two; }
public String getthree() {return three; }
public void setthree(String three) { this.three = three; }
///
如果您需要Itemactivity
或 activity.xml 我会复制。
对于res/drawable
文件夹中的文件,文件名不能以数字开头,例如111.jpg
、 222.jpg
等。因此,您可以添加以字母开头的前缀,例如image_111.jpg
, image_222.jpg
等等。
解决方案
在ItemsActivity
中,使用getIdentifier(String, String, String ) 通过资源名称 ( image_222
R.drawable.image_222
。
public class ItemActivity extends AppCompatActivity {
TextView textView;
TextView textView2;
TextView textView3;
ItemsModel itemsModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
textView2 = findViewById(R.id.textView2);
textView3 = findViewById(R.id.textView3);
Intent intent = getIntent();
if (intent.getExtras() != null) {
itemsModel = (ItemsModel) intent.getSerializableExtra("items");
textView2.setText(itemsModel.getone());
textView.setText(itemsModel.gettwo());
textView3.setText(itemsModel.getthree());
textView3.setClickable(true);
textView3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Get drawable name
String drawableName = "image_" + itemsModel.getthree();
// Find drawable resource id by drawable name
int drawableResId = getResources().getIdentifier(
drawableName,
"drawable",
getPackageName());
showImageDetail(drawableResId);
}
});
}
}
private void showImageDetail(int imageResId) {
// Using a dialog or activity to open image detail.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
ImageView imageView = new ImageView(this);
imageView.setImageResource(imageResId);
builder.setView(imageView);
builder.create().show();
}
}
更新
第一个问题是当字符串三 [] 为例如“xxx & 222”时识别“222”,所以我需要识别孔字符串内的“222”。 一些更大的字符串里面会有 222 和 333,我可以同时点击吗? 一个将显示 image_222 另一个 image_333。
这有点复杂。 例如, three
值可能是
333 yyy 444 xxx & 222
在这种情况下,您必须遍历字符串并找到图像编号,例如 333、444、222,并计算其开始和结束索引,然后使用SpannableStringBuilder.setSpan()方法为每个图像编号设置点击侦听器。
在下面的代码中,我将使用
Java 正则表达式查找three
值中的所有图像编号。
SpannableStringBuilder.setSpan()方法在图像编号上设置点击侦听器。
代码
public class ItemsActivity extends AppCompatActivity {
TextView textView;
TextView textView2;
TextView textView3;
ItemsModel itemsModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_items);
textView = findViewById(R.id.textView);
textView2 = findViewById(R.id.textView2);
textView3 = findViewById(R.id.textView3);
Intent intent = getIntent();
if (intent.getExtras() != null) {
itemsModel = (ItemsModel) intent.getSerializableExtra("items");
textView.setText(itemsModel.getone());
textView2.setText(itemsModel.gettwo());
String three = itemsModel.getthree();
SpannableStringBuilder builder = new SpannableStringBuilder(three);
String regex = three;
Pattern pattern = Pattern.compile("(\\d{3})");
Matcher matcher = pattern.matcher(regex);
while (matcher.find()) {
String imageNumber = matcher.group(0);
int numberStartIndex = three.indexOf(imageNumber);
int numberEndIndex = numberStartIndex + imageNumber.length();
builder.setSpan(new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
showImageDetailByImageNumber(imageNumber);
}
}, numberStartIndex, numberEndIndex, SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
regex = three.substring(numberEndIndex);
matcher = pattern.matcher(regex);
}
textView3.setMovementMethod(LinkMovementMethod.getInstance());
textView3.setText(builder);
}
}
/**
* Find the image drawable (image_222.jpg) based on its number name (222)
* @param imageNumber The image number like 111, 222, 333.
*/
private void showImageDetailByImageNumber(String imageNumber) {
// Get drawable name
String drawableName = "image_" + imageNumber;
// Find drawable resource id by drawable name
int drawableResId = getResources().getIdentifier(
drawableName,
"drawable",
getPackageName());
// Using a dialog or activity to open image detail.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
ImageView imageView = new ImageView(this);
imageView.setImageResource(drawableResId);
builder.setView(imageView);
builder.create().show();
}
}
第二个问题是可绘制文件夹中的图像名称必须包含小写字母和数字。 我将需要大写字母字符串(例如 A222)
在 Android 中,drawable 中的文件名必须以小写字母开头,所以我认为您只在该文件夹中使用图像前缀,例如image_
, img_
或任何符合您要求的前缀。
好的,我只是做了一个可视化的,应该是这样的。
在这一刻,第一个和第二个活动运行正常,但仅此而已。 现在我需要在代码部分中实现第二个活动,就像我给出的图像一样。 当点击“222”(在第二个活动中)它应该打开 drawable/image_222.jpg 当点击“333”(在第二个活动中)它应该打开 drawable/image_333.jpg 字符串 222 将在几个地方,例如我给猫和蜗牛。 所以如果我理解它应该是这样的:如果点击显示“drawable image_222.jpg”上的“三个是”“222”(我知道这看起来很糟糕,我只是简化了它)
Down是短ItemActivity:
TextView textView;
TextView textView2;
TextView textView3;
ItemsModel itemsModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_items_preview);
textView = findViewById(R.id.textView);
textView2 = findViewById(R.id.textView2);
textView3 = findViewById(R.id.textView3);
Intent intent = getIntent();
if(intent.getExtras() != null){
itemsModel = (ItemsModel) intent.getSerializableExtra("items");
textView2.setText(itemsModel.getone());
textView.setText(itemsModel.gettwo());
textView3.setText(itemsModel.getthree());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.