我无法让我的listview显示我的数据,它只显示空/无数据textview。
我一直试图解决这个问题一段时间,搜索了stackoverflow和网络。
尝试了很多不同的事情。
Logcat显示我的newView / bindView没有被调用/到达。
我认为这是我的XML布局中的一个错误(我的CursorAdapter不知道为我的行布局/视图充气)。
<?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="fill_parent"
android:orientation="horizontal" >
<!-- <include layout="@layout/fragment_data_table_header" /> -->
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:orientation="vertical">
</ListView>
<TextView
android:id="@android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="No Data"
android:textColor="@color/accent"
android:textSize="@dimen/text_xlarge" />
</LinearLayout>
或者我正在调用setListAdapter(或使用错误的导入?),因为我的光标测试显示它有数据。
package au.id.teda.broadband.usage.ui.fragments;
import com.actionbarsherlock.app.SherlockListFragment;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import au.id.teda.broadband.usage.R;
import au.id.teda.broadband.usage.authenticator.AccountAuthenticator;
import au.id.teda.broadband.usage.cursoradapter.DailyDataTableCursorAdapter;
import au.id.teda.broadband.usage.database.DailyDataDatabaseAdapter;
import au.id.teda.broadband.usage.helper.AccountInfoHelper;
import au.id.teda.broadband.usage.helper.AccountStatusHelper;
import au.id.teda.broadband.usage.ui.MainActivity;
public class DataTableFragment extends SherlockListFragment {
// Debug tag pulled from main activity
private final static String DEBUG_TAG = MainActivity.DEBUG_TAG;
// View inflated by fragment
private View mFragmentView;
// Helper classes
private AccountInfoHelper mAccountInfo;
private AccountStatusHelper mAccountStatus;
private AccountAuthenticator mAccountAuthenticator;
// Receive sync broadcasts
private SyncReceiver mSyncReceiver;
private IntentFilter filter;
// Activity context to be used
private Context mContext;
/**
* Called 1st in the fragment life cycle
*/
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Load helper classes
mAccountInfo = new AccountInfoHelper(activity);
mAccountStatus = new AccountStatusHelper(activity);
mAccountAuthenticator = new AccountAuthenticator(activity);
}
/**
* Called 2nd in the fragment life cycle
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set context for fragment.
// Activity extends context so we get it from there
mContext = getActivity();
// Setup broadcast receiver for background sync
String BROADCAST = getString(R.string.sync_broadcast_action);
filter = new IntentFilter(BROADCAST);
mSyncReceiver = new SyncReceiver();
}
/**
* Called 3rd in the fragment life cycle
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Set fragment layout to be inflated
mFragmentView = inflater.inflate(R.layout.fragment_data_table, container, false);
return mFragmentView;
}
/**
* Called 4th in the fragment life cycle
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DailyDataDatabaseAdapter mDatabase = new DailyDataDatabaseAdapter(mContext);
mDatabase.open();
String period = mAccountStatus.getDataBaseMonthString();
//Log.d(DEBUG_TAG, "Period to query database:" + period);
Cursor cursor = mDatabase.getPriodUsageCursor(period);
Log.d(DEBUG_TAG, "Cursor Length:" + cursor.getCount());
DailyDataTableCursorAdapter adapter = new DailyDataTableCursorAdapter(mContext, cursor, true);
//adapter.testCursor(cursor);
setListAdapter(adapter);
//cursor.close();
mDatabase.close();
}
/**
* Called 5th in the fragment life cycle
*/
@Override
public void onResume() {
super.onResume();
// Register broadcast receiver for background sync
getActivity().registerReceiver(mSyncReceiver, filter);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.d(DEBUG_TAG, "Item clicked: " + id);
}
/**
* First call in the death of fragment
*/
@Override
public void onPause() {
super.onPause();
// Unregister broadcast receiver for background sync
getActivity().unregisterReceiver(mSyncReceiver);
}
public class SyncReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent i) {
String MESSAGE = getString(R.string.sync_broadcast_message);
String SYNC_START = getString(R.string.sync_broadcast_start);
String SYNC_COMPLETE = getString(R.string.sync_broadcast_complete);
String msg = i.getStringExtra(MESSAGE);
if (msg.equals(SYNC_START)){
// Nothing to see here move along
} else if (msg.equals(SYNC_COMPLETE)){
}
}
}
}
或者我的CursorAdapter构造函数错了?所以它不知道开始膨胀和绑定视图/行
package au.id.teda.broadband.usage.cursoradapter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import au.id.teda.broadband.usage.R;
import au.id.teda.broadband.usage.database.DailyDataDatabaseAdapter;
import au.id.teda.broadband.usage.ui.MainActivity;
public class DailyDataTableCursorAdapter extends CursorAdapter {
private final static String DEBUG_TAG = MainActivity.DEBUG_TAG;
private LayoutInflater mLayoutInflater;
private Cursor mCursor;
private Context mContext;
private int COLUMN_INDEX_DAY;
private int COLUMN_INDEX_PEAK;
private int COLUMN_INDEX_OFFPEAK;
private int COLUMN_INDEX_UPLOADS;
private int COLUMN_INDEX_FREEZONE;
private int count;
private int GB = 1000000;
public DailyDataTableCursorAdapter(Context context, Cursor cursor, boolean autoRequery) {
super(context, cursor, autoRequery);
Log.d(DEBUG_TAG, "DailyDataCursorAdapter");
this.mContext = context;
this.mCursor = cursor;
this.mLayoutInflater = LayoutInflater.from(context);
this.COLUMN_INDEX_DAY = mCursor.getColumnIndex(DailyDataDatabaseAdapter.DAY);
this.COLUMN_INDEX_PEAK = mCursor.getColumnIndex(DailyDataDatabaseAdapter.PEAK);
this.COLUMN_INDEX_OFFPEAK = mCursor.getColumnIndex(DailyDataDatabaseAdapter.OFFPEAK);
this.COLUMN_INDEX_UPLOADS = mCursor.getColumnIndex(DailyDataDatabaseAdapter.UPLOADS);
this.COLUMN_INDEX_FREEZONE = mCursor.getColumnIndex(DailyDataDatabaseAdapter.FREEZONE);
}
@Override
public int getCount() {
return count;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
/**
private final class ViewHolder {
public TextView day;
public TextView peak;
public TextView offpeak;
public TextView uploads;
public TextView freezone;
public TextView total;
public TextView accum;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
Log.d(DEBUG_TAG, "DailyDataCursorAdapter.getView()");
if (mCursor.moveToPosition(position)) {
ViewHolder holder;
if (view == null) {
view = mLayoutInflater.inflate(R.layout.fragment_data_table_row, null);
holder = new ViewHolder();
holder.day = (TextView) view.findViewById(R.id.fragment_data_table_row_date);
holder.peak = (TextView) view.findViewById(R.id.fragment_data_table_row_peak);
holder.offpeak = (TextView) view.findViewById(R.id.fragment_data_table_row_offpeak);
holder.uploads = (TextView) view.findViewById(R.id.fragment_data_table_row_uploads);
holder.freezone = (TextView) view.findViewById(R.id.fragment_data_table_row_freezone);
holder.total = (TextView) view.findViewById(R.id.fragment_data_table_row_total);
holder.accum = (TextView) view.findViewById(R.id.fragment_data_table_row_accum);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
String day = LongDateToString(mCursor.getLong(COLUMN_INDEX_DAY), "dateOfMouth");
String peak = IntUsageToString(mCursor.getLong(COLUMN_INDEX_PEAK));
String offpeak = IntUsageToString(mCursor.getLong(COLUMN_INDEX_OFFPEAK));
String uploads = IntUsageToString(mCursor.getLong(COLUMN_INDEX_UPLOADS));
String freezone = IntUsageToString(mCursor.getLong(COLUMN_INDEX_FREEZONE));
String total = IntUsageToString( mCursor.getLong(COLUMN_INDEX_PEAK)
+ mCursor.getLong(COLUMN_INDEX_OFFPEAK) );
Log.d(DEBUG_TAG, "day:" + day);
Log.d(DEBUG_TAG, "peak:" + peak);
Log.d(DEBUG_TAG, "offpeak:" + offpeak);
Log.d(DEBUG_TAG, "uploads:" + uploads);
Log.d(DEBUG_TAG, "freezone:" + freezone);
Log.d(DEBUG_TAG, "totalUsageLong:" + total);
holder.day.setText(day);
holder.peak.setText(peak);
holder.offpeak.setText(offpeak);
holder.uploads.setText(uploads);
holder.freezone.setText(freezone);
holder.total.setText(total);
}
return view;
}
**/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Log.d(DEBUG_TAG, "DailyDataCursorAdapter.newView()");
// Inflate the list view with the changes above
View view = mLayoutInflater.inflate(R.layout.fragment_data_table_row, parent, false);
return view;
}
@Override
public void bindView(View row, Context context, Cursor cursor) {
Log.d(DEBUG_TAG, "DailyDataCursorAdapter.bindView()");
// Set usage text views
TextView dateTV = (TextView) row.findViewById(R.id.fragment_data_table_row_date);
TextView peakTV = (TextView) row.findViewById(R.id.fragment_data_table_row_peak);
TextView offpeakTV = (TextView) row.findViewById(R.id.fragment_data_table_row_offpeak);
TextView uploadTV = (TextView) row.findViewById(R.id.fragment_data_table_row_uploads);
TextView freezoneTV = (TextView) row.findViewById(R.id.fragment_data_table_row_freezone);
TextView totalTV = (TextView) row.findViewById(R.id.fragment_data_table_row_total);
TextView accumTV = (TextView) row.findViewById(R.id.fragment_data_table_row_accum);
// Set variables and pull data from database cursor
// TODO: Change DailyDataDBAdapter to dailyDataDBHelper???
long day = cursor.getLong(COLUMN_INDEX_DAY);
long peak = cursor.getLong(COLUMN_INDEX_PEAK);
long offpeak = cursor.getLong(COLUMN_INDEX_OFFPEAK);
long uploads = cursor.getLong(COLUMN_INDEX_UPLOADS);
long freezone = cursor.getLong(COLUMN_INDEX_FREEZONE);
long total = (peak + offpeak);
Log.d(DEBUG_TAG, "day:" + day);
Log.d(DEBUG_TAG, "peak:" + peak);
Log.d(DEBUG_TAG, "offpeak:" + offpeak);
Log.d(DEBUG_TAG, "uploads:" + uploads);
Log.d(DEBUG_TAG, "freezone:" + freezone);
Log.d(DEBUG_TAG, "total:" + total);
dateTV.setText(LongDateToString(day, "dateOfMouth"));
peakTV.setText(IntUsageToString(peak));
offpeakTV.setText(IntUsageToString(offpeak));
uploadTV.setText(IntUsageToString(uploads));
freezoneTV.setText(IntUsageToString(freezone));
totalTV.setText(IntUsageToString(total));
}
public void testCursor(Cursor cursor){
cursor.moveToFirst();
if (cursor != null){
while (cursor.moveToNext()){
long day = cursor.getLong(COLUMN_INDEX_DAY);
long peak = cursor.getLong(COLUMN_INDEX_PEAK);
long offpeak = cursor.getLong(COLUMN_INDEX_OFFPEAK);
long uploads = cursor.getLong(COLUMN_INDEX_UPLOADS);
long freezone = cursor.getLong(COLUMN_INDEX_FREEZONE);
long total = (peak + offpeak);
Log.d(DEBUG_TAG, "dateLong:" + day);
Log.d(DEBUG_TAG, "peakUsageLong:" + peak);
Log.d(DEBUG_TAG, "offpeakUsageLong:" + offpeak);
Log.d(DEBUG_TAG, "uploadUsageLong:" + uploads);
Log.d(DEBUG_TAG, "freezoneUsageLong:" + freezone);
Log.d(DEBUG_TAG, "totalUsageLong:" + total);
}
cursor.close();
}
}
// Return string values for date long millisec stored in db
private String LongDateToString(long millisecs, String convertTo) {
DateFormat date_format = null;
if (convertTo == "dayOfWeek") {
date_format = new SimpleDateFormat("EEE");
} else if (convertTo == "dateOfMouth"){
date_format = new SimpleDateFormat("dd");
} else if (convertTo == "mouthOfYear"){
date_format = new SimpleDateFormat("MMM");
}
Date resultdate = new Date(millisecs);
return date_format.format(resultdate);
}
// Return formated string value for int stored in db
private String IntUsageToString (long usage){
NumberFormat numberFormat = new DecimalFormat("#,###");
return numberFormat.format(usage/GB);
}
}
任何帮助/建议都将不胜感激。