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

片段列表:

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 为空时影响 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 回答