目前,我開始在Android開發,我想學習如何開發應用程序和應用良好的規則和建議,不能訪問內的ContentProvider光標數據。在某處我讀到,正確的做法是使用CursorLoader加載列表以加載視圖中異步的數據。此前,由於一個教程中,我創建了一個簡單的應用程序,顯示了SQLite數據庫表中的數據的列表,使用自定義適配器,我從SimpleCursorAdapter擴展,以顯示不同的圖標基礎上查詢的每一行的某些字段的值(光標)。我的自定義接口的代碼是下一個:安卓:使用CursorLoader
public class MarcaCursorAdapter extends SimpleCursorAdapter {
private Context ctx;
private Cursor cur;
public MarcaCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to, 0);
this.ctx = context;
this.cur = c;
// TODO Auto-generated constructor stub
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
convertView = View.inflate(ctx, R.layout.template_marcas, null);
View row = convertView;
ImageView imgRk = (ImageView)convertView.findViewById(R.id.tipoRanking);
//Dependiendo del ranking, cargaremos la imagen de mario o de wario
if(cur.getInt(3) % 2 == 0)
imgRk.setImageResource(R.drawable.btn1_pressed);
else
imgRk.setImageResource(R.drawable.btn1_focus);
return row;
} }
而且template_marcas.xml的內容是下一個:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:background="#002EB8"
android:paddingTop="20dp" >
<TextView
android:id="@+id/nomMarca"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textColor="#FFFFFF" />
<TextView
android:id="@+id/textView69"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/nomMarca"
android:layout_toRightOf="@+id/nomMarca"
android:text=" es la numero "
android:textColor="#FFFFFF" />
<TextView
android:id="@+id/rankMarca"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/textView69"
android:layout_toRightOf="@+id/textView69"
android:textColor="#FFFFFF" />
<ImageView
android:id="@+id/tipoRanking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/textView69"
android:layout_marginRight="56dp" /></RelativeLayout>
因此,爲了使用CursorLoader和ContentProvider的,我將我的正常類這不得不查詢表來獲得該表的遊標的方法,我從ContentProvider的延伸,並在清單文件註冊類是下一個:
public class MarcaDAO extends ContentProvider {
private ConnHandler conn;
SQLiteDatabase dbObj;
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean onCreate() {
conn = new ConnHandler(getContext());
dbObj = conn.getDb();
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor cur = dbObj.query("MARCA", projection, null, null, null, null, null);
return cur;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}}
連接,然後dbObj OBJETS AR用於管理連接,這些對象起作用。最後,我有與被覆蓋的方法實現LoaderCallbacs和活動初始化CursorLoader:
public class MarcaActivity extends Activity implements
LoaderManager.LoaderCallbacks {
//MarcaDAO dao;
MarcaCursorAdapter crsAdap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_marca);
final ListView lstMarcas = (ListView)findViewById(R.id.lstMarcas);
//Sacamos los datos de las marcas para mostrarlos en el listview
//dao = new MarcaDAO(this);
//Cursor cur = dao.getList();
getLoaderManager().initLoader(0, null, this);
crsAdap = new MarcaCursorAdapter(this, R.layout.template_marcas, null ,
new String[]{"hip_nombre", "hip_ranking"}, new int[]{R.id.nomMarca, R.id.rankMarca});
lstMarcas.setAdapter(crsAdap);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.marca, menu);
return true;
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new CursorLoader(this, Uri.parse("content://com.example.crudapp.marcaData"),
new String[]{"_id", "hip_nombre", "hip_codigo", "hip_ranking"}, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
crsAdap.swapCursor(arg1);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
crsAdap.swapCursor(null);
}}
但是,當我運行應用程序(4.2.2)我得到在MarcaCursorAdapter的方法getView一個NullPointerException在這一行:
if(cur.getInt(3) % 2 == 0)
因爲光標的行值是空的,並且如果刪除該代碼,列表加載行的確切數字,但沒有值(textviews nomMarca和rankMarca是空的),所以我不知道我做錯了。以前它沒有內容提供商,沒有光標加載器,但我想開發出好的代碼,所以我改變了我的課程。
問候。
UPDATE:對了,我忘了說,如果在活動,而不是使用MarcaCursorAdapter我只是使用SimpleCursorAdapter(失去我的方法getView的定製)的列表負載沒有問題,而且顯示的數據,所以我覺得我的問題在於我編寫了我的MarcaCursorAdapter類,但我不知道錯誤是什麼。再次
問候。
您的更改很小,所以'ViewBinder'更適合(更容易)使用。這兩種方法共同負責構建該行。如果你對其中一個的默認實現感到滿意,那麼你可以放棄實現另一個。 – Luksprog
但是,重寫newView或bindView有什麼不同? 此致敬禮。 –
是的,他們服務於不同的目的。一個構建行,一個綁定數據。你不想混在一起。 – Luksprog