0

У меня возникли проблемы с использованием «baseAdapter» для заполнения «фрагментарного списка».setListAdapter не работает должным образом

Я пытаюсь показать список со всеми музыкальными инструментами, хранящимися на моем устройстве, с помощью «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

Спасибо за вашу помощь!

ответ

1

Вы неправильно перерабатываете изображение. В методе getView вы влияете только на TextView, когда convertView равно null. Вам нужно обновлять 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; 
} 
+0

Да, я допустил ошибку в getView! Отлично работает! Спасибо! = D –

+0

Тогда вы должны отметить мой ответ как принято;) –

Смежные вопросы