我只是不明白为什么会发生这种异常。我有一个用于GridView的自定义适配器,在其中使用模型为PhotoGridItem创建类型ArrayList<PhotoGridItem>的类,这只是从SD卡提取的一堆Bitmap图像。

编译时没有错误,但是运行时得到java.lang.ClassCastException: android.graphics.Bitmap cannot be cast to org.azurespot.cutecollection.PhotoGridItem。但是它指出的行是:PhotoGridItem photoGridItem = photos.get(position);,其中没有Bitmaps通过引用,photos变量是对ArrayList<PhotoGridItem>的引用,而get()只是在该位置获取了PhotoGridItem对象。

现在... PhotoGridItem中的所有项目都是Bitmap(如模型类所示),但这不是Android Studio认为的(在编译时)。它绝对将photos.get(position);视为我的ArrayList中的PhotoGridItem对象。所以我不知道为什么会出现这种异常或如何解决它。

我基本上需要一个Bitmap来表示以下内容:holder.image.setImageBitmap(bm);但它不会接受photos.get(position);(因为在编译时它认为它是一个PhotoGriditem对象!)所以感觉就像Android Studio是对我来说有点精神分裂请帮忙,谢谢!

GridViewPhotoAdapter

package org.azurespot.cutecollection;

/**
* Created by mizu on 2/5/15.
*/
// package org.azurespot.cutecollection;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
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;

        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 photoGridItem = photos.get(position);

        Bitmap bm = photoGridItem.getImage();

        holder.image.setImageBitmap(bm);

        return row;

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return photos.size();
    }

    @Override
    public PhotoGridItem getItem(int position) {
        // TODO Auto-generated method stub
        return photos.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    static class ViewHolder {
        ImageView image;
    }

}


PhotoGridItem

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;
    }

}


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;
    }
}


Logcat

3218-3218/org.azurespot E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: org.azurespot, PID: 3218
    java.lang.ClassCastException: android.graphics.Bitmap cannot be cast to org.azurespot.cutecollection.PhotoGridItem
            at org.azurespot.cutecollection.GridViewPhotoAdapter.getView(GridViewPhotoAdapter.java:57)
            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)

最佳答案

我首先建议您为阵列适配器添加类型

public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {
...
}


也在您的PhotoTab.java中

ArrayAdapter<PhotoGridItem> adapter;


经过这两个步骤,您现在可能会收到一些错误或警告。如果没有,请在您的PhotoTab.java中检查此行

adapter.add(BitmapFactory.decodeResource(getResources(), R.drawable.ic_photo_placeholder));


这行对我来说尤其可疑,因为您要向PhotoGridItem和Array Adapter中添加位图。我想你想要的是:

adapter.add(new PhotoGridItem(BitmapFactory.decodeResource(getResources(), R.drawable.ic_photo_placeholder)));


更新资料

我还建议您不要在构造函数中传递ArrayList,因为ArrayAdapter已经由数组支持。我没有测试以下代码,但是为了说明我的想法,以下是代码:

public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {

    public Context context;
    private int resourceId;

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

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

        View row = convertView;
        ViewHolder holder;

        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 photoGridItem = getItem(position);
        Bitmap bm = photoGridItem.getImage();
        holder.image.setImageBitmap(bm);

        return row;
    }

    static class ViewHolder {
        ImageView image;
    }
}


然后在您的PhotoTab.java中:

@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);
    // Set the Adapter to GridView
    gridView.setAdapter(adapter);

    adapter.addAll(loadSDCard());

    // 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(
            new PhotoGridItem(
                BitmapFactory.decodeResource(getResources(), R.drawable.ic_photo_placeholder)));
    }

    adapter.notifyDataSetChanged();

    return v;
}

07-24 15:57