Android; setAdapter работает / не работает в зависимости от версии библиотеки поддержки Android

В настоящее время у меня есть небольшое устаревшее приложение, которое показывает текущие альбомы и их изображения в разных видах. Таким образом, один вид показывает альбомы, при выборе альбома он открывает вид, который показывает изображения выбранного альбома.

Когда приложение работает с версией 18 библиотеки поддержки Android, приложения работают нормально. Но когда я обновляю версию до 19 или выше, приложение перестает работать правильно. Это открывает представление, которое должно показать альбомы, но фактически не показывает альбомы. Смотрите в конце поста для изображений, которые иллюстрируют проблему.

Я определил проблему в следующей строке кода.

mBucketAdapter = new BucketGridAdapter(getActivity(), 0, buffer, false);
mGridView.setAdapter(mBucketAdapter); <---------

BucketGridAdapterэто пользовательский класс, который расширяет ArrayAdapter<BucketEntry>, Как видите, класс BucketGridAdapter имеет переопределение для функции getView, Эта функция вызывается в библиотеке поддержки Android версии 18, но когда я обновляю версию, она больше не вызывается.

Я заметил, что когда я закомментирую строку mGridView.setAdapter(mBucketAdapter); он показывает то же поведение, что и при обновлении версии библиотеки поддержки Android. (пустая сетка)

Проблема в том, что я не могу отладить эту строку кода mGridView.setAdapter(mBucketAdapter) и функция getView() так что я не знаю, почему getView функция не вызывается в более поздней версии библиотеки поддержки Android.

Я хотел бы помочь с этой проблемой. Если вам не хватает какой-либо информации, просто скажите об этом, и я добавлю ее.

РЕДАКТИРОВАТЬ: Обратите внимание, что получить count имеет значения на поддержку библиотеки Android версии 19 и выше, поэтомуgetView функция должна быть вызвана.

mBucketAdapter = new BucketGridAdapter(getActivity(), 0, buffer, false);
int count = mBucketAdapter.getCount(); // <-- count = 8
mGridView.setAdapter(mBucketAdapter);

Увидеть BucketImageFragment класс ниже:

package mediachooser.fragment;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.ImageColumns;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.Toast;
import com.synconset.FakeR;
import mediachooser.BucketEntry;
import mediachooser.MediaChooserConstants;
import mediachooser.activity.HomeFragmentActivity;
import mediachooser.adapter.BucketGridAdapter;

import java.util.ArrayList;

public class BucketImageFragment extends Fragment{

    // The indices should match the following projections.
    private final int INDEX_BUCKET_ID     = 0;
    private final int INDEX_BUCKET_NAME   = 1;
    private final int INDEX_BUCKET_URL    = 2;

    private static final String[] PROJECTION_BUCKET = {
        ImageColumns.BUCKET_ID,
        ImageColumns.BUCKET_DISPLAY_NAME,
        ImageColumns.DATA};

    private View mView;
    private GridView mGridView;
    private BucketGridAdapter mBucketAdapter;

    private Cursor mCursor;



    public BucketImageFragment(){
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if(mView == null){
            mView     = inflater.inflate(getRLayoutId("view_grid_layout_media_chooser"), container, false);
            mGridView = (GridView)mView.findViewById(getRIntId("gridViewFromMediaChooser"));
            init();
        }else{
            ((ViewGroup) mView.getParent()).removeView(mView);
            if(mBucketAdapter == null){
                Toast.makeText(getActivity(), getActivity().getString(getRStringId("no_media_file_available")), Toast.LENGTH_SHORT).show();
            }
        }
        return mView;
    }


    private void init(){
        final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
         mCursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION_BUCKET, null, null, orderBy + " DESC");
        ArrayList<BucketEntry> buffer = new ArrayList<BucketEntry>();
        try {
            while (mCursor.moveToNext()) {
                BucketEntry entry = new BucketEntry(
                        mCursor.getInt(INDEX_BUCKET_ID),
                        mCursor.getString(INDEX_BUCKET_NAME),mCursor.getString(INDEX_BUCKET_URL));

                if (! buffer.contains(entry)) {
                    buffer.add(entry);
                }
            }

            if(mCursor.getCount() > 0){
                mBucketAdapter = new BucketGridAdapter(getActivity(), 0, buffer, false);
                mGridView.setAdapter(mBucketAdapter); <------- THIS LINE
            }else{
                Toast.makeText(getActivity(), getActivity().getString(getRStringId("no_media_file_available")), Toast.LENGTH_SHORT).show();
            }

            mGridView.setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> adapter, View view,
                        int position, long id) {

                    BucketEntry bucketEntry  = (BucketEntry)adapter.getItemAtPosition(position);
                    Intent selectImageIntent = new Intent(getActivity(),HomeFragmentActivity.class);
                    selectImageIntent.putExtra("name", bucketEntry.bucketName);
                    selectImageIntent.putExtra("image", true);
                    selectImageIntent.putExtra("isFromBucket", true);
                    getActivity().startActivityForResult(selectImageIntent, MediaChooserConstants.BUCKET_SELECT_IMAGE_CODE);
                }
            });

        } finally {
            mCursor.close();
        }
    }

    public BucketGridAdapter getAdapter() {
        return  mBucketAdapter;
    }


    public int getRStringId(String resourceId){
        return FakeR.getId(getActivity(), "string", resourceId);
    }

    public int getRIntId(String resourceId){
        return FakeR.getId(getActivity(), "id", resourceId);
    }

    public int getRColorId(String resourceId){
        return FakeR.getId(getActivity(), "color", resourceId);
    }

    public int getRDrawableId(String resourceId){
        return FakeR.getId(getActivity(), "drawable", resourceId);
    }
    public int getRLayoutId(String resourceId){
        return FakeR.getId(getActivity(), "layout", resourceId);
    }


}

Увидеть BucketGridAdapter класс ниже.

package mediachooser.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.synconset.FakeR;
import mediachooser.BucketEntry;
import mediachooser.MediaChooserConstants;
import mediachooser.async.ImageLoadAsync;
import mediachooser.async.MediaAsync;

import java.util.ArrayList;

public class BucketGridAdapter extends ArrayAdapter<BucketEntry> {

//  public BucketVideoFragment bucketVideoFragment;

    private Context mContext;
    private ArrayList<BucketEntry> mBucketEntryList;
    private boolean mIsFromVideo;
    private int mWidth;
    LayoutInflater viewInflater;


    public BucketGridAdapter(Context context, int resource, ArrayList<BucketEntry> categories, boolean isFromVideo) {
        super(context, resource, categories);
        mBucketEntryList = categories;
        mContext         = context;
        mIsFromVideo     = isFromVideo;
        viewInflater = LayoutInflater.from(mContext);
    }

    public int getCount() {
        return mBucketEntryList.size();
    }

    @Override
    public BucketEntry getItem(int position) {
        return mBucketEntryList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public void addLatestEntry(String url) {
        int count = mBucketEntryList.size();
        boolean success = false;
        for(int i = 0; i< count; i++){
            if(mBucketEntryList.get(i).bucketName.equals(MediaChooserConstants.folderName)){
                mBucketEntryList.get(i).bucketUrl = url;
                success = true;
                break;
            }
        }

        if(!success){
            BucketEntry latestBucketEntry = new BucketEntry(0, MediaChooserConstants.folderName, url);
            mBucketEntryList.add(0, latestBucketEntry);
        }
    }

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

        ViewHolder holder;

        if (convertView == null) {

            mWidth = mContext.getResources().getDisplayMetrics().widthPixels;

            convertView  = viewInflater.inflate(getRLayoutId("view_grid_bucket_item_media_chooser"), parent, false);

            holder = new ViewHolder();
            holder.imageView    = (ImageView) convertView.findViewById(getRIntId("imageViewFromMediaChooserBucketRowView"));
            holder.nameTextView = (TextView) convertView.findViewById(getRIntId("nameTextViewFromMediaChooserBucketRowView"));

            convertView.setTag(holder);

        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        FrameLayout.LayoutParams imageParams = (FrameLayout.LayoutParams) holder.imageView.getLayoutParams();
        imageParams.width  = mWidth/3;
        imageParams.height = mWidth/3;

        holder.imageView.setLayoutParams(imageParams);

        if(mIsFromVideo){
//          new VideoLoadAsync(bucketVideoFragment, holder.imageView, false, mWidth/2).executeOnExecutor(MediaAsync.THREAD_POOL_EXECUTOR, mBucketEntryList.get(position).bucketUrl.toString());

        }else{
            ImageLoadAsync loadAsync = new ImageLoadAsync(mContext, holder.imageView, mWidth/2);
            loadAsync.executeOnExecutor(MediaAsync.THREAD_POOL_EXECUTOR, mBucketEntryList.get(position).bucketUrl);
        }

        holder.nameTextView.setText(mBucketEntryList.get(position).bucketName );
        return convertView;
    }

    class ViewHolder {
        ImageView imageView;
        TextView nameTextView;
    }

    public int getRStringId(String resourceId){
        return FakeR.getId(mContext, "string", resourceId);
    }

    public int getRIntId(String resourceId){
        return FakeR.getId(mContext, "id", resourceId);
    }

    public int getRColorId(String resourceId){
        return FakeR.getId(mContext, "color", resourceId);
    }

    public int getRDrawableId(String resourceId){
        return FakeR.getId(mContext, "drawable", resourceId);
    }
    public int getRLayoutId(String resourceId){
        return FakeR.getId(mContext, "layout", resourceId);
    }

}

Увидеть BucketEntry класс ниже

package mediachooser;

public class BucketEntry {
    public String bucketName;
    public int bucketId;
    public String bucketUrl = null;

    public BucketEntry(int id, String name, String url) {
        bucketId = id;
        bucketName = ensureNotNull(name);
        bucketUrl = url;
    }

    @Override
    public int hashCode() {
        return bucketId;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof BucketEntry)) return false;
        BucketEntry entry = (BucketEntry) object;
        return bucketId == entry.bucketId;
    }

    public static String ensureNotNull(String value) {
        return value == null ? "" : value;
    }
}

Увидеть view_grid_layout_media_chooser.xml смотреть ниже

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_height="fill_parent"
              android:layout_width="fill_parent"
              android:orientation="vertical" > <!-- android:background="@drawable/image_bg" -->

    <GridView
            android:id="@+id/gridViewFromMediaChooser"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:columnWidth="0dip"
            android:fadingEdgeLength="10dip"
            android:fastScrollEnabled="true"
            android:gravity="center"
            android:horizontalSpacing="2dip"
            android:numColumns="3"
            android:requiresFadingEdge="vertical"
            android:scrollingCache="true"
            android:stretchMode="columnWidth"
            android:verticalSpacing="2dip" />

</LinearLayout>

Увидеть view_grid_bucket_item_media_chooser.xml смотреть ниже

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <mediachooser.SquareImageView
        android:id="@+id/imageViewFromMediaChooserBucketRowView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@null"
        android:contentDescription="@null"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_loading" />

    <TextView
        android:id="@+id/nameTextViewFromMediaChooserBucketRowView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="#88666666"
        android:ellipsize="end"
        android:gravity="center"
        android:maxLines="1"
        android:text="@string/video"
        android:textColor="@android:color/white"
        android:textSize="14sp" />

</FrameLayout>

Иллюстрации изображения:

За работой:

http://i.imgur.com/WnLAhL1.png

Не работает:

http://i.imgur.com/jObA7ps.png

1 ответ

Решение

Хорошо, после поиска часов и часов и... больше часов мы нашли небольшую настройку XML представления, которая испортила видимость одного из представлений.

android:visibility="gone"

Похоже, что этот параметр XML игнорировался библиотекой поддержки Android версии 18, но при обновлении до более высокой версии использовались эти параметры.

Когда вид скрыт, либо из-за указанных выше настроек, либо из-за неправильной ширины в настройках высоты, Android не удосуживается начать писать вид. Или другими словами; использовать getView функция, которая не выполнялась в нашем случае при использовании 19-й или более поздней версии библиотеки поддержки Android.

Надеюсь, это поможет кому-то.

Другие вопросы по тегам