如何在Android中的GridView中设置ImageView的布局参数

4

我是android的新手,我在官方android网站上遇到了一个有关如何创建图像GridView的教程。我选择使用kotlin语言。在适配器类中,该类继承自BaseAdapter,我尝试按照教程中所示设置imageview的layoutparams,但是我收到一个错误,说GridView.LayoutParams未解决引用。以下是该类的完整代码:

class ImageAdapter(val context: Context) : BaseAdapter() {
    // references to our images
    val items: IntArray = intArrayOf(R.drawable.cat, R.drawable.daft_punk, R.drawable.gun, R.drawable.harvestors, R.drawable.intel, R.drawable.maserati, R.drawable.porsche, R.drawable.serveroom, R.drawable.spiderman, R.drawable.watch_dog)
    override fun getItem(p0: Int): Any {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun getItemId(p0: Int): Long {
        return 0
    }

    override fun getCount(): Int {
        return items.size
    }

    // create a new ImageView for each item referenced by the Adapter
    override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
        var imageView: ImageView
        if (p1 == null) {
      // if it's not recycled, initialize some attributes
            imageView= ImageView(context)
            imageView.layoutParams= GridView.LayoutParams(85,85)
            imageView.scaleType = ImageView.ScaleType.CENTER_CROP
            imageView.setPadding(8, 8, 8, 8)
        } else {
            imageView=p1 as ImageView
        }
        imageView.setImageResource(items[p0])
        return imageView
    }

}

错误出现在getView方法中的第imageView.layoutParams=GridView.LayoutParams(85,85)行。红色表示LayoutParams是错误的,当我将鼠标悬停在上面时,会得到以下信息:

未解决的引用:LayoutParams

我该如何成功设置这些LayoutParams?因为如果没有它们,GridView中的图像将以其完整高度显示,而我需要与我们手机上的相册应用程序显示方式相同的小图像。
后续问题:
当我将imageView.layoutParams=GridView.LayoutParams(85,85)替换为imageView.layoutParams=AbsListView.LayoutParams(85,85)时,我会收到一个javaOutOfMemory错误。以下是完整的堆栈跟踪:
08-16 06:58:11.412 4543-4543/gallerie.classmite.com.imageviewer E/dalvikvm-heap: Out of memory on a 18662416-byte allocation.
08-16 06:58:11.431 4543-4543/gallerie.classmite.com.imageviewer E/AndroidRuntime: FATAL EXCEPTION: main

Process: gallerie.classmite.com.imageviewer, PID: 4543                                                                                  java.lang.OutOfMemoryError                                                                                                                                          
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)                                                                                      
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609                                                                                      
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)                                                                                     
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)                                                                                     
at android.content.res.Resources.loadDrawable(Resources.java:2166)                                                                                     
at android.content.res.Resources.getDrawable(Resources.java:710)                                                                                      
at android.widget.ImageView.resolveUri(ImageView.java:638)                                                                                      
at android.widget.ImageView.setImageResource(ImageView.java:367)                                                                                     
at gallerie.classmite.com.imageviewer.ImageAdapter.getView(ImageAdapter.kt:32)                                                                                       
at android.widget.AbsListView.obtainView(AbsListView.java:2372)                                                                                      
at android.widget.GridView.makeAndAddView(GridView.java:1345)                                                                                      
at android.widget.GridView.makeRow(GridView.java:345)                                                                                     
at android.widget.GridView.fillDown(GridView.java:287)                                                                                      
at android.widget.GridView.fillFromTop(GridView.java:421)                                                                                      
at android.widget.GridView.layoutChildren(GridView.java:1233)                                                                                      
at android.widget.AbsListView.onLayout(AbsListView.java:2166)                                                                                      
at android.view.View.layout(View.java:15127)                                                                                      
at android.view.ViewGroup.layout(ViewGroup.java:4862)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1888)                                                                                      
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1742)                                                                                     
at android.widget.LinearLayout.onLayout(LinearLayout.java:1651)                                                                                     
at android.view.View.layout(View.java:15127)                                                                                      
at android.view.ViewGroup.layout(ViewGroup.java:4862)                                                                                     
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)                                                                                      
at android.widget.FrameLayout.onLayout(FrameLayout.java:450)                                                                                      
at android.view.View.layout(View.java:15127)                                                                                      
at android.view.ViewGroup.layout(ViewGroup.java:4862)                                                                                      
at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:374)                                                                                      
at android.view.View.layout(View.java:15127)                                                                                      
at android.view.ViewGroup.layout(ViewGroup.java:4862)                                                                                     
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)                                                                                      
at android.widget.FrameLayout.onLayout(FrameLayout.java:450)                                                                                     
at android.view.View.layout(View.java:15127)                                                                                     
at android.view.ViewGroup.layout(ViewGroup.java:4862)                                                                                     
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2315)                                                                                     
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2021)                                                                                     
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1189)                                                                                     
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6221)                                                                                     
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)                                                                                      
at android.view.Choreographer.doCallbacks(Choreographer.java:591)                                                                                     
at android.view.Choreographer.doFrame(Choreographer.java:560)                                                                                     
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)                                                                                     
at android.os.Handler.handleCallback(Handler.java:808)                                                                                      
at android.os.Handler.dispatchMessage(Handler.java:103)                                                                                      
at android.os.Looper.loop(Looper.java:193)                                                                                      
at android.app.ActivityThread.main(ActivityThread.java:5315)                                                                                      
at java.lang.reflect.Method.invokeNative(Native Method)                                                                                     
at java.lang.reflect.Method.invoke(Method.java:515)                                                                                   
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)                                                                                    
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)                                                                                     
at dalvik.system.NativeStart.main(Native Method)

只有在我手机上运行应用程序时才会出现错误,但是当我在模拟器中运行应用程序时,在进行了上述替换后,它可以完美地工作。


你加载到imageView中的图片尺寸是多少? - Sachin Chandil
最大的文件大小接近2MB,其中大部分都小于1MB... 当我加载很多小图像(比如总共超过15张)时,我会得到同样的错误。 - Sean
尝试使用 Glide 库 https://github.com/bumptech/glide。它很容易实现位图缓存和池化,并可以轻松处理您的用例。 - Sachin Chandil
好的,我一定会尝试的。 - Sean
2个回答

4
你可以尝试使用以下方法:
imageView.layoutParams = AbsListView.LayoutParams(85, 85)

AbsListView.LayoutParams被用于GridView在检索子LayoutParams时。

由于静态成员可以被Java的子类继承。当你调用GridView.LayoutParams时,实际上是在调用AbsListView.LayoutParams。然而,在Kotlin中,你不能以同样的方式做到这一点。在子类外部,你只能使用超类的名称引用其伴生对象的成员。

对后续问题的更新:

OutOfMemory错误表明你正在加载大图像到ImageView。为了避免这种情况,你必须在显示图像之前将其缩小,参考这个教程。你还可以使用一些图片加载框架,比如Glide来显示你的图片。

建议阅读:加载位图对象时出现奇怪的内存不足问题


这应该是另一个问题。你有关于它的完整堆栈跟踪吗?你可以更新问题,提及这个新问题。 - BakaWaii
如果您的图像资源过大,您可以参考这里,或者在将其传递给ImageView之前找到一种获取调整大小位图的方法。 - BakaWaii
我认为问题出在图片上。当我在模拟器中运行应用时,它可以工作,可能是因为计算机没有像手机那样对内存设置限制......我的解决方法是使用占用更少内存的较小图片,这样就解决了问题......我想制作自己版本的图库应用程序,这意味着无论图片大小如何,都将托管在手机文件管理器中而不是 drawable 文件夹中。如果我从手机获取图片,您认为我可能会遇到内存问题吗? - Sean
在Android中处理图像时,很容易遇到内存问题。为了防止这种情况发生,您必须在显示图像之前缩小图像。您还可以在这里看到一些建议。 - BakaWaii
@BakaWaii 考虑编辑你的问题,因为它对这个问题没有帮助。还要提到内存问题。任何访问者都不太可能检查评论。 - Sachin Chandil
显示剩余3条评论

0

不要像你所做的那样设置布局参数

正确的方法是 imageParams = (GridView.LayoutParams) imageView.getLayoutParams();

在上面的代码行中,“GridView”应该替换为您的imageView的父视图

编码愉快.. :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接