Android 如何使用图像填充和维护listView?

Android 如何使用图像填充和维护listView?,android,android-layout,listview,imageview,Android,Android Layout,Listview,Imageview,我想设计一个listView,这样当用户添加照片时,它会自动用图像的名称和缩略图更新listView。但是,我当前的尝试甚至没有渲染图像。是否可以为listView的每个单元格动态设置ImageView,并在向适配器添加新元素时对其进行更新 listView和add按钮的XML: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk

我想设计一个listView,这样当用户添加照片时,它会自动用图像的名称和缩略图更新listView。但是,我当前的尝试甚至没有渲染图像。是否可以为listView的每个单元格动态设置ImageView,并在向适配器添加新元素时对其进行更新

listView和add按钮的XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".Photos"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.Toolbar
        android:id="@+id/view_album_bar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    <ListView android:layout_marginTop="?android:attr/actionBarSize"
        android:id="@+id/photos_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:choiceMode="singleChoice"
        android:listSelector="@android:color/darker_gray" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/add_photo_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_marginBottom="25dp"
        android:layout_marginEnd="25dp"
        android:clickable="true"
        android:src="@drawable/plus"/>

</RelativeLayout>

活动:

    public class ViewAlbum extends AppCompatActivity {
        public Album activeAlbum;
        private ListView photoList;
        private ArrayList<String> currentPhotos = new ArrayList<String>();
        private ArrayAdapter<String> adapter;
        private int currentSelected = -1;
        public static final int PICK_IMAGE = 1;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.view_album);

            final Context context = getApplicationContext();
            Toolbar albumBar = findViewById(R.id.view_album_bar);
            setSupportActionBar(albumBar);

            photoList = findViewById(R.id.photos_list);
            Bundle bundle = getIntent().getExtras();
            String albumName = bundle.getString("album_name");
            activeAlbum = Album.loadAlbum(this.getFilesDir().getPath()+"/"+albumName+".txt");
            for(Photo photo: activeAlbum.photos){
                ImageView thumbnail = findViewById(R.id.photo_thumbnail);
                if(thumbnail == null){
                    System.out.println("why?");
                    //Don't understand why it is null, can't set image
                }
                currentPhotos.add(photo.name);
            }
            adapter = new ArrayAdapter<String>(this, R.layout.photo_cell,
                    R.id.photo_name,currentPhotos);
            photoList.setAdapter(adapter);
            photoList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    currentSelected = position;
                }
            });
            FloatingActionButton addPhotoBtn = (FloatingActionButton)findViewById(R.id.add_photo_btn);
            addPhotoBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent();
                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
                }
            });
        }
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data){
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK
                    && data != null && data.getData() != null)  {
                Uri uri = data.getData();
                Photo newPhoto = new Photo("name", uri.getPath());
                activeAlbum.photos.add(newPhoto);
                activeAlbum.saveAlbum();
            }
        }
公共类ViewAlbum扩展了AppCompative活动{
公共相册;
私有列表视图照片列表;
private ArrayList currentPhotos=新建ArrayList();
专用阵列适配器;
private int currentSelected=-1;
公共静态最终int PICK_IMAGE=1;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.view\u相册);
最终上下文=getApplicationContext();
工具栏相册栏=findViewById(R.id.view\u相册栏);
设置支持操作栏(albumBar);
照片列表=findViewById(R.id.photos\U列表);
Bundle Bundle=getIntent().getExtras();
String albumName=bundle.getString(“album_name”);
activeAlbum=Album.loadAlbum(this.getFilesDir().getPath()+“/”+albumName+“.txt”);
用于(照片:activeAlbum.photos){
ImageView缩略图=findViewById(R.id.photo\U缩略图);
如果(缩略图==null){
System.out.println(“为什么?”);
//不明白为什么为空,无法设置图像
}
currentPhotos.add(photo.name);
}
适配器=新阵列适配器(此,R.layout.photo_单元,
R.id.照片(姓名、当前照片);
photoList.setAdapter(适配器);
photoList.setOnItemClickListener(新的AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
当前选择=位置;
}
});
FloatingActionButton addPhotoBtn=(FloatingActionButton)findViewById(R.id.add\u photo\u btn);
addPhotoBtn.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
意图=新意图();
intent.setType(“image/*”);
intent.setAction(intent.ACTION\u GET\u CONTENT);
startActivityForResult(Intent.createChooser(Intent,“选择图片”),PICK_IMAGE);
}
});
}
@凌驾
ActivityResult上的公共void(int请求代码、int结果代码、意图数据){
super.onActivityResult(请求代码、结果代码、数据);
如果(requestCode==PICK_IMAGE&&resultCode==Activity.RESULT_确定
&&数据!=null&&data.getData()!=null){
Uri=data.getData();
Photo newPhoto=newPhoto(“name”,uri.getPath());
activeAlbum.photos.add(newPhoto);
activeAlbum.saveAlbum();
}
}
每个ListView单元格:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:attr/activatedBackgroundIndicator">

    <LinearLayout android:id="@+id/thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="3dip"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="5dip">

        <ImageView
            android:id="@+id/photo_thumbnail"
            android:layout_width="106dp"
            android:layout_height="77dp" />
    </LinearLayout>

    <TextView
        android:id="@+id/photo_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="25dp"
        android:text="Album Name"
        android:textColor="#0984e3"
        android:textSize="25dip"
        android:textStyle="bold"
        android:typeface="sans" />

</RelativeLayout>

当您在OnActivityResult()上获得结果时,将其添加到currentPhotos,
然后在OnActivityResult()上获得结果时调用notifyDataSetChanged()

,将其添加到currentPhotos,
然后调用notifyDataSetChanged()

首先,我认为
album.photo
与创建适配器时传递的数组不同(
currentPhotos
)。因此,向album.photo添加新照片不会在listView中反映该项


其次,正如用户开发人员所指出的,每当您更改数据时,您都需要通过
adapter.notifyDataSetChanged()
告诉适配器。但是在您的情况下,您总是在末尾添加内容,我认为最好调用
adapter.notifyDataInserted(currentPhotos.size()-1)

首先,我认为
album.photo
与创建适配器(
currentPhotos
)时传递的数组不同。因此,向album.photo添加新照片不会在listView中反映该项


其次,正如用户开发人员所指出的,每当您更改数据时,您都需要通过
adapter.notifyDataSetChanged()
告诉适配器。但是在您的情况下,您总是在末尾添加内容,我认为最好调用
adapter.notifyDataInserted(currentPhotos.size()-1)

如果您正在处理本地存储或web上的图像。使用像
实现'com.squareup.picasso:picasso:2.71828'
这样的库可能是一个好主意,因为它可以处理基于图像和URL的异常,并捕获数据,以便更容易打开应用程序。如果您需要,内存可以被最少地使用。

使用本地存储或web上的图像。使用库(如
实现'com.squareup.picasso:picasso:2.71828'
)可能是一个好主意,因为它可以处理基于图像和URL的异常,并捕获数据,以便更容易打开应用程序。内存可以最低限度地使用。

好的,这是有意义的,但我仍然不知道我不明白为什么:ImageView缩略图=findViewById(R.id.photo\u缩略图);为空,无论我在哪里调用它。这是因为MainActivity的XML文件中不存在
R.id.photo_缩略图
。它只存在于项目的XML中,因此您无法从MainActivity访问它。相反,更新ListView项目应该在适配器内完成。要实现这一点,您可能必须创建一个适配器类从ArrayAdapter继承,并提供一些公共方法来更新缩略图。希望我有意义。好吧,这有意义,但我仍然不明白为什么:ImageView缩略图=findViewById(R.id.photo\u缩略图);为空,无论我在哪里调用它。Th