图像适配器 Xamarin Android

Image Adapter Xamarin Android

先了解一下背景:我正在制作一个图库作为我应用程序的一部分,因为我发现无法在 android 中导入多张图片。为此,下面的代码访问相机目录,然后通过适配器将图像放在 GridView 中,但适配器在列表而不是网格中显示图片,还有一个更大的问题是应用程序不会在加载后大约一秒钟崩溃,但它确实显示了 Xamarin 水印(此版本仅适用于 24 小时消息)。

我需要你帮助的问题是,为什么我的应用程序不会 运行 在 phone 中,为什么它会在模拟器中 运行,其次为什么它显示在列表中而不是网格?

我选择了写外部存储和读外部存储权限。

如果有人能帮助我,我将不胜感激。

我的主文件

public class MainActivity : Activity
{
    List<string> URIs=new List<string> ();// un parsed URIs

    List<ImageView> IMGs;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
        SetContentView(Resource.Layout.Main);

        IMGs = new List<ImageView> ();
        GetImageFileNames ();
        MakeImageViews ();

        Toast.MakeText (this,"this is sparta",ToastLength.Short).Show ();

        GridView gridView = FindViewById<GridView> (Resource.Id.gridView1);

        PicAdapter PA=  new PicAdapter (this,IMGs);

        gridView.Adapter = PA; 

        }

    void MakeImageViews ()
    {   
        foreach (string uri in URIs) 
        {
            Android.Net.Uri _uri = Android.Net.Uri.Parse(uri);
            ImageView imageView = new ImageView(this);
            imageView.LayoutParameters = new GridView.LayoutParams (85, 85);
            imageView.SetScaleType (ImageView.ScaleType.CenterCrop);
            imageView.SetPadding (8, 8, 8, 8);
            imageView.SetImageURI (_uri);
            IMGs.Add (imageView);

        }
    }

    #region GetFileNames

    void  GetImageFileNames ()
    {
        //ImageView imageView = FindViewById<ImageView> (Resource.Id.imageView1);
        DirectoryInfo dir = new DirectoryInfo (Android.OS.Environment.GetExternalStoragePublicDirectory (Android.OS.Environment.DirectoryDcim).AbsolutePath + "/Camera");
        if (dir.Exists == true) {
            FileInfo[] file = dir.GetFiles ();
            foreach (FileInfo file2 in file) {
                if (file2.Extension == ".jpg" || file2.Extension == ".jpeg" || file2.Extension == ".gif" ||
                    file2.Extension == ".png") {

                    URIs.Add (file2.ToString ());
                }
            }
    //      ImageView ImageView = FindViewById<ImageView> (Resource.Id.imageView1);
    //      ImageView.SetImageURI (URIs [1]);
            //  
        } else {
            Toast.MakeText (this, "Can not read files from camera folder or no files in camera folder", ToastLength.Short).Show ();
        }

    }

    #endregion
}

适配器

public class PicAdapter: BaseAdapter<ImageView>
{   Context context;
    List<ImageView> IMGs;
    public PicAdapter (Context c,List<ImageView> imgs)
    {
        this.context = c;
        this.IMGs = imgs;

    }


    #region implemented abstract members of BaseAdapter
    public override long GetItemId (int position)
    {
        return position;
    }
    public override Android.Views.View GetView (int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
    {
        View tile = convertView;

        if (tile == null)
        {
            tile = LayoutInflater.From(context).Inflate(Resource.Layout.SinglePicTile,null,false);

        }
        ImageView picture = tile.FindViewById<ImageView>(Resource.Id.PicTile); // here you are making each grid view tiles
        picture = IMGs [position];
        return picture;
    }

    public override int Count {
        get {return IMGs.Count;}
    }
    #endregion

    #region implemented abstract members of BaseAdapter
    public override ImageView this [int index] {
        get {
            return IMGs [index];
        }
    }
    #endregion
}

Xaml、Main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/gridView">
    <GridView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/gridView1" />
</LinearLayout>

适配器模板:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:minWidth="25px"
    android:minHeight="25px">
    <ImageView
        android:src="@android:drawable/ic_menu_gallery"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:id="@+id/PicTile"
        android:padding="10dp"
        android:maxWidth="100dp"
        android:maxHeight="100dp"
        android:cropToPadding="true" />
</LinearLayout>

而不是创建 ImageView 个实例并将它们交给您的 Adapter。相反,您应该只将字符串列表交给它并让它处理初始化。否则你很快就会 运行 内存不足。

所以将您的 Adapter 更改为:

public class PicAdapter : BaseAdapter<string>
{
    private List<string> _imageUrls = new List<string>();

    public void AddImage(string uri)
    {
        _imageUrls.Add(uri);
    }

    ...
}

然后在 GetView 中,您将实例化视图,或重复使用前一个单元格中的视图并设置 URI,该 URI 包含在您传递给 Adapter 的字符串之一中。

你的问题基本上出在这一行:

picture = IMGs [position];

这段代码并没有神奇地将ImageView添加到布局中,您需要操作从FindViewById获得的ImageView:

public override View GetView (int position, View convertView, ViewGroup parent)
{
    var view = convertView;

    if (view == null)
        view = LayoutInflater.From(context).Inflate(Resource.Layout.SinglePicTile, parent, false);

    var picture = tile.FindViewById<ImageView>(Resource.Id.PicTile);
    picture.SetImageURI(Android.Net.Uri.Parse(_imageUrls[position]));
    return picture;
}

所以基本上放弃 MakeImageViews() 方法,因为这是 Adapter 应该处理的事情。