我在使用'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调用此方法的次数和结果(仅用于举例说明):
- &GT; size = 30
- &GT;调用该方法的次数:16
感谢您的帮助!
答案 0 :(得分: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;
}