How to add a row dynamically in a tableLayout in A

2019-02-15 14:22发布

问题:

I have a function who gets a list of products from a webpage, and I want to add a row in a tableLayout for each element of the list.

public void getProductsOfCategory() throws IOException{
        new Thread(){
            public void run(){
                //background code...
                try {
                    Bundle extras = getIntent().getExtras();
                    String categoryName = extras.getString("categoryName");

                    HttpGet httpget = new HttpGet("http://romal.hopto.org/foodadvisor/users/getProductsOfCategory.json?category="+categoryName);
                    HttpResponse httpresp = httpClient.execute(httpget);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    httpresp.getEntity().writeTo(baos);
                    final String content = new String(baos.toByteArray());
                    CategoryActivity.this.runOnUiThread(new Runnable(){
                        public void run(){
                            //foreground code (UI)
                            //update user interface, for example, showing messages
                            try {
                                JSONObject jObject = new JSONObject(content);
                                JSONArray productsList = jObject.getJSONArray("response");
                                for(int i=0; i<productsList.length();i++){
                                    JSONObject product = productsList.getJSONObject(i);
                                    JSONObject productData = product.getJSONObject("Product");
                                    String productDescription = productData.getString("description");
                                }
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }   
                        }
                    });
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }.start();
    }

In my layout xml file I have defined the table layout like this:

<TableLayout
            android:id="@+id/tableOfProducts"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <TextView
                android:id="@+id/productDescription"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="TextView"
                android:paddingBottom="7dp"
                android:paddingLeft="14dp"
                android:paddingRight="14dp"
                android:paddingTop="7dp"
                android:textSize="20dp" />

        </TableLayout>

I imagine I have to add some extra code in the for loop, adding a new row and a new textview for each element, and setting the content of the text view with the string that has the description of the product. How can I do this?

回答1:

Check this out, this is the general way of creating table rows dynamically. Modify it accordingly

XML file

<TableLayout 
xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/main_table"
android:layout_height="wrap_content" 
android:layout_width="match_parent">
</TableLayout> 

JAVA PART

TableLayout t1;

TableLayout tl = (TableLayout) findViewById(R.id.main_table);

Create table row header to hold the column headings

TableRow tr_head = new TableRow(this);
tr_head.setId(10);
tr_head.setBackgroundColor(Color.GRAY);        // part1
tr_head.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));

I'm adding two data sections to the table row

TextView label_hello = new TextView(this);
         label_hello.setId(20);
         label_hello.setText("HELLO");
         label_hello.setTextColor(Color.WHITE);          // part2
         label_hello.setPadding(5, 5, 5, 5);
         tr_head.addView(label_hello);// add the column to the table row here

         TextView label_android = new TextView(this);    // part3
         label_android.setId(21);// define id that must be unique
         label_android.setText("ANDROID..!!"); // set the text for the header  
         label_android.setTextColor(Color.WHITE); // set the color
         label_android.setPadding(5, 5, 5, 5); // set the padding (if required)
         tr_head.addView(label_android); // add the column to the table row here

After adding the columns to the table row its time to add the table row the the main table layout that we fetched at the start

tl.addView(tr_head, new TableLayout.LayoutParams(
                 LayoutParams.FILL_PARENT,                    //part4
                 LayoutParams.MATCH_CONTENT));      

EDIT : YOU CAN DO THE FOLLOWING IN YOUR CODE

 TextView[] textArray = new TextView[productsList.length()];
 TableRow[] tr_head = new TableRow[productsList.length()];

 for(int i=0; i<productsList.length();i++){
 JSONObject product = productsList.getJSONObject(i);
 JSONObject productData = product.getJSONObject("Product");
 String productDescription = productData.getString("description");

//Create the tablerows
tr_head[i] = new TableRow(this);
tr_head[i].setId(i+1);
tr_head[i].setBackgroundColor(Color.GRAY);
tr_head[i].setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));

 // Here create the TextView dynamically

 textArray[i] = new TextView(this);
         textArray[i].setId(i+111);
         textArray[i].setText(productDescription);
         textArray[i].setTextColor(Color.WHITE);
         textArray[i].setPadding(5, 5, 5, 5);
         tr_head[i].addView(textArray[i]);

// Add each table row to table layout

tl.addView(tr_head[i], new TableLayout.LayoutParams(
                     LayoutParams.MATCH_PARENT,
                     LayoutParams.WRAP_CONTENT));

} // end of for loop

Creating the TextView and TableRow array are not necessary. You can just include part1, part2, part3 (if you need more than 1 field) and part4 inside your for loop.



回答2:

Look, i think you have to modify your xml to adding rows to your tableview:

First, the inflater:

 LayoutInflater inflater = mContext.getLayoutInflater();

or in this way:

 LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);



 //Here you can set up the layoutparameters from your tableview and the rowview.
 //Maybe you don't have to modify nothing from the parameters of your tableview so
 //you can dismiss it.

 TableLayout.LayoutParams tableParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT);
 TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);

 //Here were we take the tablelayout from your xml
 TableLayout tableLayout = (TableLayout)inflater.inflate(R.layout.tableOfProducts, null);

 //Like a told you before, maybe you don't need set the parameters of the tablelayout
 //so you can comment next line.
 tableLayout.setLayoutParams(this.tableParams);

 TableRow tableRow = new TableRow(context);
 tableRow.setLayoutParams(this.tableParams);

 //Here you have to create and modify the new textview.
 TextView textView = new TextView(context);
 textView.setLayoutParams(this.rowParams);

 tableRow.addView(textView);

 tableLayout.addView(tableRow);

If you need more help, tell me, if it is helpful, rating me!!! ;) Un saludo Gallega! O como se dice en gallego: una aperta!



回答3:

for this, you have to create one xml file for row, then you have to modify your layout.xml file like

<ScrollView>
  <LinearLayout orientation=vertical id="+id/rowHolder">
  </LinearLayout
</scrollview>

Then in for loop, inflate the row layout and add it runtime to rowHolder object.



回答4:

I'm new myself to Android, and after years with Python/Gtk, I'm lost if I can't think in terms of Model/View/Presenter.

one useful approach I managed to apply, it puts me back into that optics, and even if it's not relative to a Table, I'm quite sure it can be extended to that (I guess this page would be a good start, for me too).

start by declaring the two objects in your fragment (or activity):

List<String> stringList;  // think of it as the model.
ArrayAdapter<String> listAdapter;  // and this would be the presenter

define the model in the fragment constructor:

stringList = new ArrayList<>();

next, when the onCreateView of my fragment is invoked, I do this (edit correspondingly if you're using Activity, not Fragment):

View rootView = inflater.inflate(R.layout.fragment_taxonomy, container, false);
ListView mainListView = rootView.findViewById(R.id.taxonomy_results);

// Create ArrayAdapter using the string list.  think of it as the presenter.
// see how it's being handled a model and a view.
listAdapter = new ArrayAdapter<>(
        rootView.getContext(), R.layout.textrow, stringList);

// Set the ArrayAdapter as the ListView's adapter.
mainListView.setAdapter( listAdapter );

textrow.xml is an extra layout which is being reused every time I add an element to the stringList model.

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rowTextView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="16sp" >
</TextView>

in the rest of the code, I only "talk" to listAdapter, and I only need its two add and clear methods, to add elements, or for clearing the list.