2017-05-30 54 views
0

這是我的情況: 我有一個GridLayout(在活動開始時,它的某些單元格中有一些textview,但我將更改它以稍後動態生成這些textviews),我想將一些textViews放入它的一些細胞。如何在AsyncTask上生成TextView並將其放置在GridLayout上?

問題:我不知道我需要多少個textViews。它取決於數據庫的信息。此外,我不知道如何將生成的textViews從AsyncTask添加到gridLayout。

所以,我一直在尋找一些答案,但我無法使它的工作。我嘗試了類似this的東西,但不是我正在尋找的東西(我創建了一個新的TextView,但不能將它添加到該線程的gridLayout中)。 這是我的應用程序的工作流程:

1º我用gridLayout開始活動。它有一些textViews: 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, wich obtains a Strategy 
     e.execute(this.getApplicationContext(), "proyecto", this, this.grid);//I sended a lot of things to test if something gives result 
    } 
} 

2º在該主類,我開始用的AsyncTask一個新線程,從一個SQLite數據庫獲取數據。 這是面料:

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'來查看我創建的時間列表中有多少個對象。對於heach對象,我想創建一個TextView,並將其添加到gridLayout(即在主線程中)。

最後,從對方的回答接口:

public interface onTextViewCreatedListener { 
    public void onTextViewCreated(TextView tv); 
} 

我希望你能幫助我。謝謝。

EDIT_1:我需要使用與UI線程不同的其他線程,因爲我需要在數據庫中搜索數據。

+0

也許你可以從異步任務只返回文本和創建textviews ...或者你可以使用runOnuiThread()方法在這裏解釋說:https://stackoverflow.com/questions/12850143/android-basics -uunning-code-in-the-ui-thread –

+0

只需包含list-view - > text-view。基於數組列表文本視圖的大小是動態創建的。 – sivaprakash

+0

代替網格視圖嘗試使用回收器視圖或帶適配器的可擴展列表視圖。 –

回答

0

你必須拆分你的邏輯,在AsyncTask或簡單的新線程()中搜索DB中的數據,然後創建UI元素並將它們附加到UI線程中。

mActivity 
     .runOnUiThread(
       new Runnable() { 

        @Override 
        public void run() { 
         //create a TextView, and add it to the gridLayout 
        } 
       }); 
相關問題