GridView自定义适配器具有CastClassException

时间:2015-03-20 03:43:08

标签: android gridview arraylist android-arrayadapter

我试图模糊地使用tutorialGridView创建自己的自定义适配器,但是我的适配器中的教程出现了一行问题,但我一直遇到错误它。 PhotoGridItem item = photos.get(position);如果我按原样保留该行,则为红色,并说“#{1;}不兼容的类型,期待PhotoGridItem,找到Object"。所以我尝试将(PhotoGridItem)转换为它,它消除了错误,但在运行时我得到一个ClassCastException,表示"无法将位图强制转换为PhotoGridItem" 。但我不知道还有什么可以尝试。

有什么想法吗?感谢。

更新

根据建议,我将所有ArrayList()更改为ArrayList<PhotoGridItem>,然后我将位图图像输出方法略微更改为photoList.add(new PhotoGridItem(bitmap));没有编译错误,但仍然得到java.lang.ClassCastException: android.graphics.Bitmap cannot be cast to org.azurespot.cutecollection.PhotoGridItem我的适配器中的行:PhotoGridItem item = photos.get(position);。以下代码已更新。

PhotoTab.java

    package org.azurespot.cutecollection;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;

import org.azurespot.R;

import java.io.File;
import java.util.ArrayList;

/**
 * Created by mizu on 2/8/15.
 */
public class PhotoTab extends Fragment{

    private GridView gridView;
    File[] files;
    ArrayList<PhotoGridItem> photoList = new ArrayList<>();
    ArrayAdapter adapter;

    public PhotoTab(){
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.photo_tab, container, false);

        // with fragments, make sure you include the rootView when finding id
        gridView = (GridView) v.findViewById(R.id.photo_grid);
        adapter = new GridViewPhotoAdapter(getActivity(), R.layout.photo_grid_item,
                                                                    loadSDCard());
        // Set the Adapter to GridView
        gridView.setAdapter(adapter);

        // add the default icons remaining, to GridView, if less than 24 files on SD card
        for (int i = 0; i < (24 - photoList.size()); i++) {

            adapter.add(BitmapFactory.decodeResource(getResources(), R.drawable.ic_photo_placeholder));
            adapter.notifyDataSetChanged();
            i++;
        }

        return v;
    }


    private ArrayList<PhotoGridItem> loadSDCard(){

        try {
            // gets directory CutePhotos from sd card
            File baseDir = Environment.getExternalStorageDirectory();
            File cutePhotoDir = new File(baseDir, "/Documents/CutePhotos");
            // lists all files in CutePhotos, loads in Files[] array
            files = cutePhotoDir.listFiles();


            for (File singleFile : files) {
                String filePath = singleFile.getAbsolutePath();
                Bitmap bitmap = BitmapFactory.decodeFile(filePath);
                photoList.add(new PhotoGridItem(bitmap));
            }

        } catch (Exception e){
            e.printStackTrace();
        }

        return photoList;
    }

}

GridViewPhotoAdapter.java

    package org.azurespot.cutecollection;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

import org.azurespot.R;

import java.util.ArrayList;

/**
* Created by mizu on 2/5/15.
*/
public class GridViewPhotoAdapter extends ArrayAdapter {

    public Context context;
    private int resourceId;
    private ArrayList<PhotoGridItem> photos = new ArrayList<>();


    public GridViewPhotoAdapter(Context context, int layoutResourceId, ArrayList<PhotoGridItem> photos) {
        super(context, layoutResourceId, photos);
        this.context = context;
        this.resourceId = layoutResourceId;
        this.photos = photos;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = convertView;
        ViewHolder holder = null;

        if (row == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(resourceId, parent, false);
            holder = new ViewHolder();
            holder.image = (ImageView) row.findViewById(R.id.photo_grid_view);
            row.setTag(holder);
        } else {
            holder = (ViewHolder) row.getTag();
        }

        PhotoGridItem item = photos.get(position);

        holder.image.setImageBitmap(item.getImage());

        return row;

    }

    static class ViewHolder {
        ImageView image;
    }

}

PhotoGridItem.java

package org.azurespot.cutecollection;

import android.graphics.Bitmap;

/**
 * Created by mizu on 3/19/15.
 */
public class PhotoGridItem {

    private Bitmap image;

    public PhotoGridItem(Bitmap image) {
        super();
        this.image = image;
    }

    public Bitmap getImage() {
        return image;
    }

    public void setImage(Bitmap image) {
        this.image = image;
    }

}

logcat的

FATAL EXCEPTION: main
    Process: org.azurespot, PID: 5080
    java.lang.ClassCastException: android.graphics.Bitmap cannot be cast to org.azurespot.cutecollection.PhotoGridItem
            at org.azurespot.cutecollection.GridViewPhotoAdapter.getView(GridViewPhotoAdapter.java:49)
            at android.widget.AbsListView.obtainView(AbsListView.java:2791)
            at android.widget.GridView.onMeasure(GridView.java:1065)
            at android.view.View.measure(View.java:17619)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
            at android.view.View.measure(View.java:17619)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at android.view.View.measure(View.java:17619)
            at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1456)
            at android.view.View.measure(View.java:17619)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
            at android.view.View.measure(View.java:17619)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at android.view.View.measure(View.java:17619)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
            at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:453)
            at android.view.View.measure(View.java:17619)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at android.view.View.measure(View.java:17619)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
            at android.view.View.measure(View.java:17619)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2588)
            at android.view.View.measure(View.java:17619)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2317)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1412)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1613)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1270)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6691)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:813)
            at android.view.Choreographer.doCallbacks(Choreographer.java:613)
            at android.view.Choreographer.doFrame(Choreographer.java:583)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:799)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5731)
            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:1291)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
            at dalvik.system.NativeStart.main(Native Method)

4 个答案:

答案 0 :(得分:1)

  

问题是您已经制作了ArrayList of objects而不是PhotoGridItem的ArrayList

所以将其转换为ArrayList<PhotoGridItem>

  

Expanation

这是因为您没有指定ArrayList包含PhotoGridItem,而不是ArrayList<PhotoGridItem>,而是您没有指定任何内容,默认情况下它只是对象并返回Object.Make a类似于ArrayList的PhotoGridItem列表

  

更改

在您的片段类实例变量中

ArrayList photoList = new ArrayList();

ArrayList<PhotoGridItem> photoList = new ArrayList<PhotoGridItem>();

更改此

private ArrayList loadSDCard(){

    try {
        // gets directory CutePhotos from sd card
        File baseDir = Environment.getExternalStorageDirectory();
        File cutePhotoDir = new File(baseDir, "/Documents/CutePhotos");
        // lists all files in CutePhotos, loads in Files[] array
        files = cutePhotoDir.listFiles();


        for (File singleFile : files) {
            String filePath = singleFile.getAbsolutePath();
            Bitmap bitmap = BitmapFactory.decodeFile(filePath);
            photoList.add(bitmap);
        }

    } catch (Exception e){
        e.printStackTrace();
    }

    return photoList;
}

private ArrayList<PhotoGridItem> loadSDCard(){

    try {
        // gets directory CutePhotos from sd card
        File baseDir = Environment.getExternalStorageDirectory();
        File cutePhotoDir = new File(baseDir, "/Documents/CutePhotos");
        // lists all files in CutePhotos, loads in Files[] array
        files = cutePhotoDir.listFiles();


        for (File singleFile : files) {
            String filePath = singleFile.getAbsolutePath();
            Bitmap bitmap = BitmapFactory.decodeFile(filePath);
            photoList.add(new PhotoGridItem(bitmap));
        }

    } catch (Exception e){
        e.printStackTrace();
    }

    return photoList;
}

更改此

private ArrayList photos = new ArrayList();


public GridViewPhotoAdapter(Context context, int layoutResourceId, ArrayList photos) {
    super(context, layoutResourceId, photos);
    this.context = context;
    this.resourceId = layoutResourceId;
    this.photos = photos;
}

private ArrayList<PhotoGridItem> photos = new ArrayList<PhotoGridItem>();


public GridViewPhotoAdapter(Context context, int layoutResourceId, ArrayList<PhotoGridItem> photos) {
    super(context, layoutResourceId, photos);
    this.context = context;
    this.resourceId = layoutResourceId;
    this.photos = photos;
}

答案 1 :(得分:1)

正如其他人提到你的arraylist声明是错误的。 ArrayList是泛型类型,因为它们可以包含任何相同类型的对象。但是您需要提供此arraylist应该保留的数据类型信息。

ArrayList<PhotoGridItem> photoList = new ArrayList<PhotoGridItem>();
GridViewPhotoAdapter adapter; // this should not be ArrayAdapter

教程网站的问题是泛型类型,如&lt;整数&gt; 可能被视为像&lt; html标签一样身体&gt;。我发现Stackoverflow也有这个问题。

答案 2 :(得分:0)

更改getView GridViewPhotoAdapter方法,如下所述。您正在将Bitmap直接添加到ArrayList。您未在PhotoGridItem方法中使用loadSDCard。如果您需要PhotoGridItem,请尝试使用ArrayList填充PhotoGridItem

@Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = convertView;
        ViewHolder holder = null;

        if (row == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(resourceId, parent, false);
            holder = new ViewHolder();
            holder.image = (ImageView) row.findViewById(R.id.photo_grid_view);
            row.setTag(holder);
        } else {
            holder = (ViewHolder) row.getTag();
        }

        //PhotoGridItem item =  photos.get(position);

        //holder.image.setImageBitmap(item.getImage());

        holder.image.setImageBitmap(photos.get(position));
        return row;

    }

答案 3 :(得分:0)

实际上,您只是在loadSDCard()

中错过了这一点
  photoList.add(new PhotoGridItem(bitmap));