在图像适配器中从sqlite中获取图像路径(Xamarin Android C#上的GridView)。

问题描述 投票:0回答:1

我想在网格视图中显示我的图片。图片来自于路径,而路径存储在SQLite数据库中。我尝试了MSDN的教程,在这里。https:/docs.microsoft.comen-usxamarinandroiduser-interfacelayoutsgrid-view。 我修改了我的resource.drawable.image,并把它改成了图片路径(图片路径来自数据库),但我不知道该怎么做。我试着用位图的方法,但我仍然不知道如何用这种方法把它变成数组。我想从数据库中获取图片数据,如图片标题、图片描述和图片路径,并将其存储到我的List<>或数组中。

我已经建立了数据库,并尝试调用它,但是,我还是很困惑。请帮助我。

所以,这是一个表的对象类。它叫做Photo.cs

[Table("tblPhoto")]
    public class Photo
    {
        [PrimaryKey, AutoIncrement, Column("pkPhotoID")]
        public int PhotoID { get; set; }
    [Column("fkUserID")]
    public int UserID { get; set; }
    public string PhotoPath { get; set; }
    public string PhotoName { get; set; }
    public string PhotoDescription { get; set; }
    private DateTime _creationDate;

    public string CreationDate
    {
        get { return _creationDate.ToString(); }
        set { _creationDate = DateTime.ParseExact(value, "yyyy:MM:dd HH:mm:ss", null); }
    }

    private DateTime _uploadDate;
    public string UploadDate
    {
        get { return _uploadDate.ToString(); }
        set { _uploadDate = DateTime.Parse(value); }
    }
    //show User Photo
    public static Photo ShowUserPhoto()
    {
        return DBManager.Instance.Query<Photo>($"SELECT * FROM tblPhoto a JOIN tblUser b WHERE a.UserID== b.UserID").FirstOrDefault();
    }

    //show photo path and its photo
    public static Photo ShowPhotoPath(string aPhotoPath)
    {
        return DBManager.Instance.Query<Photo>($"SELECT * FROM tblPhoto WHERE PhotoPath=='{aPhotoPath}'").FirstOrDefault();
    }

    //show all
    public static Photo ShowAllPhoto()
    {
        return DBManager.Instance.Query<Photo>($"SELECT * FROM tblPhoto").FirstOrDefault();
    }

第二个是ImageAdapter,因为我想在gridview中显示图片。它被称为ImageAdapter.cs

public class ImageAdapter : BaseAdapter
    {
        private Context context;
        private List<string> gridViewString;
        private List<string> gridViewImage;
        public ImageAdapter(Context context, List<string> gridViewstr, List<string> gridViewImage)
        {
            this.context = context;
            gridViewString = gridViewstr;
            this.gridViewImage = gridViewImage;
        }
        public override int Count
        {
            get
            {
                return gridViewString.Count;
            }
        }
    public override Java.Lang.Object GetItem(int position)
    {
        return null;
    }

    public override long GetItemId(int position)
    {
        return 0;
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View view;
        LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
        if (convertView == null)
        {
            view = new View(context);
            view = inflater.Inflate(Resource.Layout.gridview_layout, null);
            TextView txtview = view.FindViewById<TextView>(Resource.Id.textPhotoTitleViewGrid);
            ImageView imgview = view.FindViewById<ImageView>(Resource.Id.imageViewGrid);

            txtview.Text = gridViewString[position];
            imgview.SetImageBitmap(GetImageBitmapFromDB(gridViewImage[position]));
        }
        else
        {
            view = (View)convertView;
        }
        return view;
    }

    private Android.Graphics.Bitmap GetImageBitmapFromDB(string aPath)
    {
        Android.Graphics.Bitmap imageBitmap = null;

        var _getPath = Model.Photo.ShowPhotoPath(aPath);
        {
            var imgPath = _getPath.ShowPhotoPath(aPath);
            if (imgPath != null && imgPath.Length > 0)
            {
                imageBitmap = Android.Graphics.BitmapFactory.DecodeFile(imgPath);
            }
        }
        return imageBitmap;
    }
}

最后一个是一个叫做Fragment_home.cs的片段类,图片应该显示在这里。

public class Fragment_Home : Android.Support.V4.App.Fragment
    {
        List<string> m_gridviewstring = new List<string>();
        List<string> m_imgview = new List<string>();
        GridView m_gridview;
        public override void OnCreate(Bundle aSavedInstanceState)
        {
            base.OnCreate(aSavedInstanceState);
        }

        public static Fragment_Home NewInstance()
        {
            var _frag1 = new Fragment_Home { Arguments = new Bundle() };
            return _frag1;
        }

        public override View OnCreateView(LayoutInflater aInflater, ViewGroup aContainer, Bundle aSavedInstanceState)
        {
            var _ignored = base.OnCreateView(aInflater, aContainer, aSavedInstanceState);
            //String stringData = Arguments.GetString("email");
            View _view =  aInflater.Inflate(Resource.Layout.FragmentHome, null);

            //var gridview = _view.FindViewById<GridView>(Resource.Id.gridview);
            //gridview.Adapter = new ImageAdapter(Context);

            //gridview.ItemClick += Gridview_ItemClick;

            //return _view;

            var _retrievePic = Model.Photo.ShowAllPhoto();
            //_retrievePic.PhotoPath;

            ImageAdapter adapter = new ImageAdapter(Activity, m_gridviewstring, m_imgview);
            m_gridview = _view.FindViewById<GridView>(Resource.Id.grid_view_image_text);
            m_gridview.Adapter = adapter;
            return _view;
        }
    }

请帮帮我,有什么帮助吗?

c# android xamarin xamarin.android
1个回答
0
投票

我把两张图片贴在 /storage/emulated/0/DCIM/Camera/ 路径和 "/storage/emulated/0/Pictures" 路径也是如此。为了测试,我重新命名了照片的名字。

下面是正在运行的gif(请忽略巢状碎片,我不想从头到尾创建一个新的演示,我使用了我以前的演示)。

enter image description here

首先,我创建了一个 PhotoDAO.cs读取数据时,会将数据插入到DB中,并从DB中读取所有数据。在插入数据到DB时,我给了一个PhotoPath和PhotoName。

  public class PhotoDAO
    {
      static  SQLiteConnection db;

        public List<Photo> GetAllPhotos()
        {
            Console.WriteLine("Reading data");
            var table = db.Table<Photo>();
            List<Photo> photos = table.ToList<Photo>();


            return photos;
        }
        public static void DoSomeDataAccess()
        {
            Console.WriteLine("Creating database, if it doesn't already exist");
            string dbPath = Path.Combine(
                 System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal),
                 "Photo1.db3");
            db = new SQLiteConnection(dbPath);
            db.CreateTable<Photo>();
            if (db.Table<Photo>().Count() == 0)
            {
                // only insert the data if it doesn't already exist
                var newPhoto1 = new Photo();
                newPhoto1.UserID = 1;
                newPhoto1.PhotoPath = "/storage/emulated/0/Pictures/";
                newPhoto1.PhotoName = "icon.png";
                newPhoto1.PhotoDescription = "This is a hamburger";
                db.Insert(newPhoto1);

                var newPhoto2 = new Photo();
                newPhoto2.UserID = 2;
                newPhoto2.PhotoPath = "/storage/emulated/0/Pictures/";
                newPhoto2.PhotoName = "person.jpg";
                newPhoto2.PhotoDescription = "This is a person";
                db.Insert(newPhoto2);

                var newPhoto3 = new Photo();
                newPhoto3.UserID = 3;
                newPhoto3.PhotoPath = "/storage/emulated/0/DCIM/Camera/";
                newPhoto3.PhotoName = "IMG1.jpg";
                newPhoto3.PhotoDescription = "This is a IMG1";
                db.Insert(newPhoto3);

                var newPhoto4 = new Photo();
                newPhoto4.UserID = 4;
                newPhoto4.PhotoPath = "/storage/emulated/0/DCIM/Camera/";
                newPhoto4.PhotoName = "IMG2.jpg";
                newPhoto4.PhotoDescription = "This is a IMG2";
                db.Insert(newPhoto4);

            }  
        }
    }

然后在 Fragment_Gallery.cs,我们设置一个 Adapter 对于 GridView. 这里是代码。

    public class Fragment_Gallery : Android.Support.V4.App.Fragment
    {
        public override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Create your fragment here
        }
        public static Fragment_Gallery NewInstance()
        {
            var frag1 = new Fragment_Gallery { Arguments = new Bundle() };
            return frag1;
        }
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {

            var ignored = base.OnCreateView(inflater, container, savedInstanceState);
            View view = inflater.Inflate(Resource.Layout.galleryfragment, null);

            var gridview = view.FindViewById<GridView>(Resource.Id.gridview);

            PhotoDAO.DoSomeDataAccess();
            var photoDAO=new PhotoDAO();
            List<Photo> photos=photoDAO.GetAllPhotos();
            gridview.Adapter = new MyAdapter(this, photos);
            return view;
        }
    }

这是我的gridview Adapter的代码。我创建了一个CustomView用于测试,如果你将来需要自定义gridview中的项目。我从本地路径设置了Imageview源,请看这里。 GetView 方法。

    internal class MyAdapter :BaseAdapter<Photo>
    {
        private Fragment_Gallery fragment_Gallery;
        private List<Photo> photos;

        public MyAdapter(Fragment_Gallery fragment_Gallery, List<Photo> photos)
        {
            this.fragment_Gallery = fragment_Gallery;
            this.photos = photos;
        }

        public override Photo this[int position] => photos[position];

        public override int Count => photos.Count;



        public override long GetItemId(int position)
        {
           return position;
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {

            View view = convertView;
            if (view == null) // no view to re-use, create new
                view = fragment_Gallery.LayoutInflater.Inflate(Resource.Layout.CustomView, null);
            view.FindViewById<TextView>(Resource.Id.custUserID).Text = photos[position].UserID.ToString();
            view.FindViewById<TextView>(Resource.Id.custPhotoPath).Text = photos[position].PhotoPath;
            view.FindViewById<TextView>(Resource.Id.custPhotoName).Text = photos[position].PhotoName;
            view.FindViewById<TextView>(Resource.Id.custPhotoDescription).Text = photos[position].PhotoDescription;
            string imgFile = photos[position].PhotoPath + photos[position].PhotoName;
            Bitmap myBitmap = BitmapFactory.DecodeFile(imgFile);

            view.FindViewById<ImageView>(Resource.Id.custImage).SetImageBitmap(myBitmap);
            return view;
        }


    }

以下是关于 CustomView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView  
    android:layout_width="200dp"
    android:layout_height="200dp" 
    android:id="@+id/custImage" />
    <TextView
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:id="@+id/custUserID" 
    android:text="@string/abc_action_bar_home_description"
    />
    <TextView
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:id="@+id/custPhotoPath" 
    android:text="@string/abc_action_bar_home_description"
    />
    <TextView
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:id="@+id/custPhotoName" 
    android:text="@string/abc_action_bar_home_description"
    />
        <TextView
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:id="@+id/custPhotoDescription" 
    android:text="@string/abc_action_bar_home_description"
    />



</LinearLayout>

最后,请不要忘了加注 android.permission.WRITE_EXTERNAL_STORAGE 在你 AndroidManifest.xml

这是我的演示,你可以下载后做个测试(请像我的PersonDAO类一样添加图片,也可以在PersonDAO类中更改图片名称)。

https:/drive.google.comfiled1ipw534Q0C4UxHva3Jiv5SoI0KycifpmIview?usp=分享。

===更新==========。

如果你想实现点击事件,你可以使用 gridview.ItemClick += Gridview_ItemClick; 来实现。如果你从适配器中得到的图像位置没有找到,请添加一个断点。Photo photo = photos[e.Position];Gridview_ItemClick如果你的e.Position正确的话。

   public class Fragment_Gallery : Android.Support.V4.App.Fragment
    {
        public override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Create your fragment here
        }
        public static Fragment_Gallery NewInstance()
        {
            var frag1 = new Fragment_Gallery { Arguments = new Bundle() };
            return frag1;
        }
        List<Photo> photos;
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {

            var ignored = base.OnCreateView(inflater, container, savedInstanceState);
            View view = inflater.Inflate(Resource.Layout.galleryfragment, null);

            GridView gridview = view.FindViewById<GridView>(Resource.Id.gridview);
            gridview.ItemClick += Gridview_ItemClick;

            PhotoDAO.DoSomeDataAccess();
            var photoDAO=new PhotoDAO();
            photos=photoDAO.GetAllPhotos();

            gridview.Adapter = new MyAdapter(this, photos);
            return view;
        }

        private void Gridview_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            // throw new NotImplementedException();

            Photo photo = photos[e.Position];
            Intent intent= new Intent(Context, typeof(DetailActivity));
            intent.PutExtra("PicName", photo.PhotoName);
            intent.PutExtra("PicDes", photo.PhotoDescription);
            StartActivity(intent);
        }
    }

在DetailActivity中,你可以通过以下代码来获取图片信息。

   public class DetailActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.Detaillayout);
            TextView detailPhotoName = FindViewById<TextView>(Resource.Id.detailPhotoName);
            TextView detailPhotoDescription = FindViewById<TextView>(Resource.Id.detailPhotoDescription);

            Bundle extras =Intent.Extras;
            detailPhotoName.Text = extras.GetString("PicName");
            detailPhotoDescription.Text = extras.GetString("PicDes");
            // Create your application here
        }
    }

你想在片段布局或在图中显示更大的图片。DetailActivity? 在片段布局中,只需将该片段中的 columnWidth=200dpGridView 并打开 CustomView.xml,设置更大的值为 android:layout_width="200dp" android:layout_height="200dp"ImageView

这里是点击运行的gif。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.