我的代码没有错误,但是当我运行应用程序时,屏幕只是空白。
有没有人知道为什么会这样?
我的目标是,一旦我完成了这项工作,我想将来自 json 提要的数据添加到其中。
这是我的活动:
import android.app.ListActivity;
import android.content.Context;
import android.database.CharArrayBuffer;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore.Audio.Media;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
import co.uk.listapp.myapp.util.NotifyingAsyncQueryHandler;
import co.uk.listapp.myapp.util.NotifyingAsyncQueryHandler.NotifyingAsyncQueryListener;
/**
* Shows a smart way of handling separators in {@link ListView}s. It also shows
* some ways to boost your {@link ListView}s using techniques like 'section
* caching', ViewHolder, CharArrayBuffer, etc.
*
*/
public class ChooseTeamActivity extends ListActivity implements NotifyingAsyncQueryListener {
private AudioFilesAdapter mAdapter;
private NotifyingAsyncQueryHandler mQueryHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new AudioFilesAdapter(this, null);
setListAdapter(mAdapter);
// Starts querying the media provider. This is done asynchronously not
// to possibly block the UI or even worse fire an ANR...
mQueryHandler = new NotifyingAsyncQueryHandler(getContentResolver(), this);
mQueryHandler.startQuery(Media.EXTERNAL_CONTENT_URI, AudioFilesQuery.PROJECTION, AudioFilesQuery.SORT_ORDER);
}
@Override
protected void onDestroy() {
// Clear any strong reference to this Activity
mQueryHandler.clearQueryListener();
super.onDestroy();
}
public void onQueryComplete(int token, Object cookie, Cursor cursor) {
if (cursor != null) {
startManagingCursor(cursor);
}
mAdapter.changeCursor(cursor);
}
private static class AudioFilesViewHolder {
public TextView separator;
public TextView titleView;
public CharArrayBuffer titleBuffer = new CharArrayBuffer(128);
}
private static class AudioFilesAdapter extends CursorAdapter {
/**
* State of ListView item that has never been determined.
*/
private static final int STATE_UNKNOWN = 0;
/**
* State of a ListView item that is sectioned. A sectioned item must
* display the separator.
*/
private static final int STATE_SECTIONED_CELL = 1;
/**
* State of a ListView item that is not sectioned and therefore does not
* display the separator.
*/
private static final int STATE_REGULAR_CELL = 2;
private final CharArrayBuffer mBuffer = new CharArrayBuffer(128);
private int[] mCellStates;
public AudioFilesAdapter(Context context, Cursor cursor) {
super(context, cursor);
mCellStates = cursor == null ? null : new int[cursor.getCount()];
}
@Override
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
mCellStates = cursor == null ? null : new int[cursor.getCount()];
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final AudioFilesViewHolder holder = (AudioFilesViewHolder) view.getTag();
/*
* Separator
*/
boolean needSeparator = false;
final int position = cursor.getPosition();
cursor.copyStringToBuffer(AudioFilesQuery.TITLE, holder.titleBuffer);
switch (mCellStates[position]) {
case STATE_SECTIONED_CELL:
needSeparator = true;
break;
case STATE_REGULAR_CELL:
needSeparator = false;
break;
case STATE_UNKNOWN:
default:
// A separator is needed if it's the first itemview of the
// ListView or if the group of the current cell is different
// from the previous itemview.
if (position == 0) {
needSeparator = true;
} else {
cursor.moveToPosition(position - 1);
cursor.copyStringToBuffer(AudioFilesQuery.TITLE, mBuffer);
if (mBuffer.sizeCopied > 0 && holder.titleBuffer.sizeCopied > 0 && mBuffer.data[0] != holder.titleBuffer.data[0]) {
needSeparator = true;
}
cursor.moveToPosition(position);
}
// Cache the result
mCellStates[position] = needSeparator ? STATE_SECTIONED_CELL : STATE_REGULAR_CELL;
break;
}
if (needSeparator) {
holder.separator.setText(holder.titleBuffer.data, 0, 1);
holder.separator.setVisibility(View.VISIBLE);
} else {
holder.separator.setVisibility(View.GONE);
}
/*
* Title
*/
holder.titleView.setText(holder.titleBuffer.data, 0, holder.titleBuffer.sizeCopied);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = LayoutInflater.from(context).inflate(R.layout.single_item, parent, false);
// The following code allows us to keep a reference on the child
// views of the item. It prevents us from calling findViewById at
// each getView/bindView and boosts the rendering code.
AudioFilesViewHolder holder = new AudioFilesViewHolder();
holder.separator = (TextView) v.findViewById(R.id.separator);
holder.titleView = (TextView) v.findViewById(R.id.title);
v.setTag(holder);
return v;
}
}
// Keep query data in one place
private interface AudioFilesQuery {
String[] PROJECTION = {
Media._ID, Media.TITLE, Media.ALBUM, Media.ARTIST
};
int TITLE = 1;
//int ALBUM = 2;
//int ARTIST = 3;
String SORT_ORDER = Media.TITLE + " ASC";
}
}
NotfyingAsyncQueryHandler
import java.lang.ref.WeakReference;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
/**
* A particular {@link AsyncQueryHandler} allowing clients to be notified via a
* listener. The {@link NotifyingAsyncQueryHandler} also make sure no strong
* reference is kept on the given listener (as it is often a Context).
*
*/
public class NotifyingAsyncQueryHandler extends AsyncQueryHandler {
private WeakReference<NotifyingAsyncQueryListener> mListener;
/**
* Client may use this to listen to completed query operations.
*/
public interface NotifyingAsyncQueryListener {
void onQueryComplete(int token, Object cookie, Cursor cursor);
}
public NotifyingAsyncQueryHandler(ContentResolver resolver, NotifyingAsyncQueryListener listener) {
super(resolver);
setQueryListener(listener);
}
/**
* Assign the given {@link NotifyingAsyncQueryListener}.
*/
public void setQueryListener(NotifyingAsyncQueryListener listener) {
mListener = (listener != null) ? new WeakReference<NotifyingAsyncQueryListener>(listener) : null;
}
public void clearQueryListener() {
mListener = null;
}
public void startQuery(Uri uri, String[] projection) {
startQuery(-1, null, uri, projection, null, null, null);
}
public void startQuery(Uri uri, String[] projection, String sortOrder) {
startQuery(-1, null, uri, projection, null, null, sortOrder);
}
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
final NotifyingAsyncQueryListener listener = (mListener == null) ? null : mListener.get();
if (listener != null) {
listener.onQueryComplete(token, cookie, cursor);
} else if (cursor != null) {
cursor.close();
}
}
}
single_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="@android:color/white">
<TextView
style="?android:attr/listSeparatorTextViewStyle"
android:id="@+id/separator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/white" />
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="@color/blue"
android:textSize="16sp"
android:textStyle="bold"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingLeft="8dp" />
</LinearLayout>