如何在AsyncTask上生成TextView并将其放置在GridLayout上?

问题描述 投票:0回答:1

这是我的情况: 我有一个 GridLayout (在活动开始时,它的某些单元格中有一些文本视图,但我将更改它以动态生成这些文本视图),并且我想在其中的几个单元格中放置一些文本视图。

问题:我不知道我需要多少个textView。这取决于数据库的信息。此外,我不知道如何将 AsyncTask 生成的 textView 添加到 gridLayout 中。

所以,我一直在寻找一些答案,但我无法使其发挥作用。我尝试了类似 this 的内容,但并不完全是我想要的(我创建了一个新的 TextView,但无法将其从该线程添加到 gridLayout 中)。 这是我的应用程序的工作流程:

1º 我使用 gridLayout 启动活动。它有一些文本视图: image

这是主要活动:

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线程不同的其他线程,因为我需要在数据库中搜索数据。

java android android-asynctask textview grid-layout
1个回答
0
投票

您必须拆分逻辑,在 AsyncTask 或简单的 new Thread() 中搜索数据库中的数据,然后创建 UI 元素并将它们附加到 UI 线程中。

mActivity
       .runOnUiThread(
               new Runnable() {

                    @Override
                    public void run() {
                        //create a TextView, and add it to the gridLayout
                    }
                });
© www.soinside.com 2019 - 2024. All rights reserved.