0

「baseAdapter」を使用して「fragmentList」を埋めるのに問題があります。

「MediaStore.Audio.Media」を使用してデバイスに保存されているすべての音楽のリストを表示しようとしていますが、プログラムが setListAdapter 関数を呼び出すときに問題が発生します。baseAdapter へのアイテムの数が少し多い場合、リストの一部のみが正しく入力されます。

baseAdapter コード:

public class MListAdapter extends BaseAdapter {

public static final Integer KEY_LAYOUT_TITLE = 0;
public static final Integer KEY_LAYOUT_SUBTITLE = 1;
public static final Integer KEY_LAYOUT_OTHERS = 2;
public static final Integer KEY_LAYOUT_IMAGE_ID = 3;
public static final Integer KEY_LAYOUT_LIST = 4;

private ArrayList<String> arrayString;

private LayoutInflater lInflater = null;    
private Context context;

public MListAdapter(Context ctx, ArrayList<String> arrString){

    context = ctx;
    arrayString = arrString;

    lInflater = LayoutInflater.from(ctx);

}

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

public String getItem(int position) {
    return arrayString.get(position);
}

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


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

    if (convertView == null) {
       mView = lInflater.inflate(R.layout.frag_music_list, null);
       TextView mTitle = (TextView) mView.findViewById(R.id.musicNameTextView);
       //TextView mSubtitle = (TextView) mView.findViewById(R.id.musicArtistAlbumTextView);
       //TextView mOthers = (TextView) mView.findViewById(R.id.musicDurationTextView);
       //ImageView mImage = (ImageView) mView.findViewById(R.id.thumbImageView);


       mTitle.setText(getItem(position));
       Log.d("DEBUG",String.valueOf(position));
       Log.d("DEBUG",String.valueOf(getCount()));


       //mSubtitle.setText(hashItem.get(KEY_LAYOUT_SUBTITLE));
       //mOthers.setText(hashItem.get(KEY_LAYOUT_OTHERS));

    }
    return mView;
}

FragmentList:

public class MListFragment extends ListFragment {

MListFragmentListener mCallback;
InterfaceFragmentMusic typeMusicCallback;

// --- Global Variables
static ArrayList<HashMap<Integer, String>> mapString = null;
static ArrayList<HashMap<Integer, Long>> mapImage = null;

// ---The URIs used to get a group of music and its informations
Uri uriMedias = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

/**
 * ---The following vectors of strings are used to choose what kind of
 * information will be retrieved from the database in each case (the
 * columns)
 */

final String[] columnsMedias = { 
        MediaStore.Audio.Media.DISPLAY_NAME,
        MediaStore.Audio.Media.ALBUM_ID, 
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media.ALBUM, 
        MediaStore.Audio.Media.DURATION

};

// The container Activity must implement this interface so the frag can
// deliver messages
public interface MListFragmentListener {
    /**
     * Called by MListFragment when a list item is selected It has been
     * implemented in the FragMusicActivity class!
     **/
    public void onMusicSelected(String musicName);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // The system initially shows the list with all the musics
    updateMList(MusicTypeFragment.KEY_POSITION_ALLSONGS);

}

@Override
public void onStart() {
    super.onStart();

    // When in two-pane layout, set the listview to highlight the selected
    // list item
    // (We do this during onStart because at the point the listview is
    // available.)
    //if (getFragmentManager().findFragmentById(R.id.music_fragment) != null) {
    //  getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    //}
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception.
    try {
        mCallback = (MListFragmentListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement MListFragmentListener");
    }
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {

    // Set the item as checked to be highlighted when in two-pane layout
    getListView().setItemChecked(position, true);
}

/**
 * This fragment will be updated/refreshed whatever the user choose a music
 * option on the menu (on the left side)
 **/

/* It refreshes/updates the current list with a new type */
public void updateMList(int position) {
    Cursor cursor;
    MListAdapter mAdapter = null;

    ContentResolver cr = getActivity().getContentResolver();

    cursor = cr.query(uriMedias, columnsMedias, null, null, null);
    ArrayList<String> arrString = new ArrayList<String>();

    populateMap(cursor, arrString);     
    mAdapter = new MListAdapter(getActivity(),arrString);


    int a = mAdapter.getCount();

    for (int i = 0; i < a; i++) {
        Log.d("MLISTFRAG", mAdapter.getItem(i));
    }


    this.setListAdapter(mAdapter);

     cursor.close();
}

/*
 * It populates an arrayList with the information about the musics using the
 * data passed by a cursor
 */
private void populateMap(Cursor c, ArrayList<HashMap<Integer, String>> array,   ArrayList<String> arrString) {

    Cursor mCursor = c;
    while (mCursor.moveToNext()) {
        // creating new HashMap
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        // Values by default
        //map.put(MListAdapter.KEY_LAYOUT_TITLE,
        //      getString(R.string.inBlank));
        //map.put(MListAdapter.KEY_LAYOUT_SUBTITLE,
        //      getString(R.string.inBlank));
        //map.put(MListAdapter.KEY_LAYOUT_OTHERS,
        //      getString(R.string.inBlank));

        // New values
        map.put(MListAdapter.KEY_LAYOUT_TITLE,
                mCursor.getString(MListAdapter.KEY_LAYOUT_TITLE));

        arrString.add(mCursor.getString(MListAdapter.KEY_LAYOUT_TITLE));
        array.add(map);
    }
    mCursor.close();
}

これらのコードの結果は、リストが部分的に正しいことを示しています。つまり、リストの前半は問題ありませんが、後半は最初の部分の繰り返しです。Log.d を getView (baseAdapter 内) に入れて、配列のサイズが正しいかどうか、および setListAdapter がこのメソッドを呼び出す回数と結果 (例示のみ) を確認します。

--> サイズ = 30

--> メソッドが呼び出された回数: 16

ご協力いただきありがとうございます!

4

1 に答える 1

1

ビューを適切にリサイクルしていません。getView メソッドでは、convertView が null の場合にのみ TextView に影響を与えます。毎回 TextView を更新する必要があります。このような :

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

    if (mView == null) {
       mView = lInflater.inflate(R.layout.frag_music_list, null);
    }
    TextView mTitle = (TextView) mView.findViewById(R.id.musicNameTextView);
    mTitle.setText(getItem(position));

    return mView;
}
于 2013-10-13T21:09:21.897 に答える