这是我的情况: 我有一个 GridLayout (在活动开始时,它的某些单元格中有一些文本视图,但我将更改它以动态生成这些文本视图),并且我想在其中的几个单元格中放置一些文本视图。
问题:我不知道我需要多少个textView。这取决于数据库的信息。此外,我不知道如何将 AsyncTask 生成的 textView 添加到 gridLayout 中。
所以,我一直在寻找一些答案,但我无法使其发挥作用。我尝试了类似 this 的内容,但并不完全是我想要的(我创建了一个新的 TextView,但无法将其从该线程添加到 gridLayout 中)。 这是我的应用程序的工作流程:
1º 我使用 gridLayout 启动活动。它有一些文本视图:
这是主要活动:
public class MostrarProyectos extends AppCompatActivity {
private final String TAG = "MostrarProyectos";
//Para obtener de un hilo no principal los proyectos:
public static ArrayList<Proyecto> listaDeProyectos = new ArrayList<>();
public GridLayout grid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mostrar_proyectos);
grid = (GridLayout) findViewById(R.id.grid);
EstrategiaObtenerObjetoDB e = FabricaEstrategiaObtenerDB.getInstance().construirEstrategia("proyecto", this); //This is a Fabric, which obtains a Strategy
e.execute(this.getApplicationContext(), "proyecto", this, this.grid);//I sent a lot of things to test if something gives result
}
}
2° 在该主类中,我使用 AsyncTask 启动了一个新线程,以从 SQLite DB 获取数据。 这是面料:
public class FabricaEstrategiaObtenerDB {
private static final FabricaEstrategiaObtenerDB ourInstance = new FabricaEstrategiaObtenerDB();
public static FabricaEstrategiaObtenerDB getInstance() {
return ourInstance;
}
private FabricaEstrategiaObtenerDB() {}
public EstrategiaObtenerObjetoDB construirEstrategia(String tabla, Activity acti){
switch(tabla){
//Some other cases
case "proyecto":
EstrategiaObtenerObjetoDBProyecto p = new EstrategiaObtenerObjetoDBProyecto(acti, new onTextViewCreatedListener() {
@Override
public void onTextViewCreated(TextView tv) {
//I don't know what to do here
}
}); //This code I tried from the other stackOverflow answer
return p;
default:
return null;
}
}
}
这是一个从数据库获取对象的抽象类:
public abstract class EstrategiaObtenerObjetoDB extends AsyncTask<Object, Void, ArrayList<Object>> {
protected onTextViewCreatedListener onTextViewCreatedListener; //part of the code from the other StackOverflow user.
Activity miActividad;
public EstrategiaObtenerObjetoDB(Activity act, onTextViewCreatedListener onTextViewCreatedListener){
this.onTextViewCreatedListener = onTextViewCreatedListener; //This is too code from the other user.
this.miActividad = act;
}
@Override
protected ArrayList<Object> doInBackground(Object... params) {
AppDbHelper mDbHelper = new AppDbHelper(miActividad.getApplicationContext());
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = obtenerSelect();
Cursor c = armarQuery(db, (String)params[1], projection); //params[1] is the name of the table in the DB
ArrayList<Object> arrayDeObjetos = new ArrayList<>();
try{
arrayDeObjetos.add(miActividad.getApplicationContext());//add the context
arrayDeObjetos.add(miActividad.findViewById(R.id.grid));//add the grid
armarObjetos(c);
return arrayDeObjetos;
}catch (Exception e){
String b = e.getMessage();
return null;
}
}
@Override
protected abstract void onPostExecute(ArrayList<Object> objects);
protected abstract String[] obtenerSelect();
protected abstract Cursor armarQuery(SQLiteDatabase db, String tabla, String[] projection);
protected abstract void armarObjetos(Cursor c);
}
具体策略是这样的:
public class EstrategiaObtenerObjetoDBProyecto extends EstrategiaObtenerObjetoDB {
public EstrategiaObtenerObjetoDBProyecto(Activity act,onTextViewCreatedListener onTextViewCreatedListener) {
super(act,onTextViewCreatedListener);
}
@Override
protected String[] obtenerSelect() {
String[] projection = {
AppContract.Proyecto._ID,
AppContract.Proyecto.COLUMN_NOMBRE,
AppContract.Proyecto.COLUMN_DESCRIPCION,
AppContract.Proyecto.COLUMN_PRIORIDAD,
AppContract.Proyecto.COLUMN_ANIO,
AppContract.Proyecto.COLUMN_MES,
AppContract.Proyecto.COLUMN_SEMANA,
AppContract.Proyecto.COLUMN_DURACION,
};
return projection;
}
@Override
protected Cursor armarQuery(SQLiteDatabase db, String tabla, String[] projection) {
Cursor cursor = db.query(
tabla,
projection,
null,
null,
null,
null,
null
);
return cursor;
}
@Override
protected void armarObjetos(Cursor c) {
c.moveToFirst();
ArrayList<Object> proyectos = new ArrayList<>();
do {
try{
String nombre = c.getString(c.getColumnIndex(AppContract.Proyecto.COLUMN_NOMBRE));
String descripcion = c.getString(c.getColumnIndex(AppContract.Proyecto.COLUMN_DESCRIPCION));
String prioridad = c.getString(c.getColumnIndex(AppContract.Proyecto.COLUMN_PRIORIDAD));
String anio = c.getString(c.getColumnIndex(AppContract.Proyecto.COLUMN_ANIO));
String mes = c.getString(c.getColumnIndex(AppContract.Proyecto.COLUMN_MES));
String semana = c.getString(c.getColumnIndex(AppContract.Proyecto.COLUMN_SEMANA));
String duracion = c.getString(c.getColumnIndex(AppContract.Proyecto.COLUMN_DURACION));
Proyecto p = new Proyecto(nombre,descripcion, prioridad, anio, mes, semana, duracion);
MostrarProyectos.listaDeProyectos.add(p);
proyectos.add(p);
}catch(Exception e){
Log.d("EstrategiaObtenerPr",e.getMessage());
}
} while (c.moveToNext());
}
@Override
protected void onPostExecute(ArrayList<Object> objects) {
MostrarProyectos.listaDeProyectos.add((Proyecto)objects.get(i));
GridLayout grid = (GridLayout) miActividad.findViewById(R.id.grid);
if(!MostrarProyectos.listaDeProyectos.isEmpty()){
for(int numeroTemporal = 0; numeroTemporal<MostrarProyectos.listaDeProyectos.size();numeroTemporal++){
Proyecto j = MostrarProyectos.listaDeProyectos.get(numeroTemporal);
TextView text = new TextView(miActividad.getApplicationContext());
text.setText(j.getNombre());
int numFila = MostrarProyectos.contarFilas(j.getMes(), j.getSemana());
GridLayout.LayoutParams params3 = new GridLayout.LayoutParams();
params3.rowSpec = GridLayout.spec(numFila);//,Integer.parseInt(j.getDuracion())
Log.d("MostrarProyecto", numFila+","+Integer.parseInt(j.getDuracion()));
params3.columnSpec = GridLayout.spec(3);
text.setLayoutParams(params3);
try{
if(onTextViewCreatedListener!=null){
onTextViewCreatedListener.onTextViewCreated(text);//from the other user
}
}catch (Exception excepcion){
Log.d("MostrarProyecto", excepcion.getMessage());
}
}
}
else{
Toast.makeText(miActividad.getApplicationContext(),"No hay proyectos",Toast.LENGTH_LONG);
}
MostrarProyectos.terminoCargaDatos = true;
}
}
3° 获取数据后,我想生成与从数据库中获取的对象一样多的 TextView,因此我使用“for”来查看我创建的临时列表中有多少个对象。对于每个对象,我想创建一个 TextView,并将其添加到 gridLayout (即在主线程上)。
最后,来自其他答案的界面:
public interface onTextViewCreatedListener {
public void onTextViewCreated(TextView tv);
}
我希望你能帮助我。谢谢你。
EDIT_1:我需要使用与UI线程不同的其他线程,因为我需要在数据库中搜索数据。
您必须拆分逻辑,在 AsyncTask 或简单的 new Thread() 中搜索数据库中的数据,然后创建 UI 元素并将它们附加到 UI 线程中。
mActivity
.runOnUiThread(
new Runnable() {
@Override
public void run() {
//create a TextView, and add it to the gridLayout
}
});