1

I would like to implement a gridview within Android, which will basically consist of 4 columns (it will be actiing similary to a table).

This will essentially be a list of items spread across 4 columns (name, qty, p1, p2). So each row contains 4 columns is unique to 1 items. Therefore, I need a way to bind these 4 columns together so that when i select anywhere within those 4 columns the whole row will be selected, whilst returning the 'name' column as the text id.

Is there an easy way that this can be done? This is my current code for the gridView:

XML Layout:

<GridView
    android:id="@+id/gvShopCompleteList"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/spnShopCharacters"
    android:layout_above="@+id/linerBuyBtns"
    android:numColumns="1"
    android:fastScrollEnabled="true"
    android:scrollbarStyle="insideOverlay">
</GridView>

Binding of Dynamic content:

GridView gridview;
static final String[] listItems = new String[] { "name","qty","p1","p2","itemname","5","100","1" };
gridview = (GridView)findViewById(R.id.gvShopCompleteList);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listItems);
gridview.setAdapter(adapter);

gridview.setOnItemClickListener(new OnItemClickListener() 
{
    public void onItemClick(AdapterView<?> parent, View v,int position, long id) 
    {
        Toast.makeText(getApplicationContext(),
        ((TextView) v).getText(), Toast.LENGTH_SHORT).show();
    }
});

Finally, an additional feature I would like to add is to make the header read only and highlighted a different color to the other rows. Any help would be much appreciated here, I do not have to use GridView, but would like to keep the generic android look as much as possible (consistant throughout my app). Thanks.

SingleWave Games
  • 2,618
  • 9
  • 36
  • 52
  • What you want is a `ListView` where each row contains your four columns. The first position will be made unclickable in the custom adapter that you'll need to implement. Should be really easy to implement. – user Nov 21 '12 at 15:45
  • Will i be able to line the ListView up correctly if I combine all 4 of my columns into the 1 row (as it needs to essentially act like a table)? I will be using 4 different ArrayLists to fill the data. – SingleWave Games Nov 21 '12 at 15:49
  • Yes, for example if the "columns" are 4 `TextViews` you could easily spread them evenly across all rows by putting them into a `LinearLayout` and assigning them a `weight` of `1`. – user Nov 21 '12 at 15:52
  • perfect, will give this a go. I assume that the ListView will automatically bind all 4 TextViews into 1 row, therefore when the user click the whole row light up? – SingleWave Games Nov 21 '12 at 15:56
  • The entire row will be highlighted, setting the data on the `TextViews` will be your responsibility in your custom adapter. – user Nov 21 '12 at 15:58
  • Do you mind chucking together a quick clippet of code (XML Layout). Mainly how in regards to the layout, not too fussed about adding the data to the TextView? – SingleWave Games Nov 21 '12 at 16:15

1 Answers1

2

I've made a little sample. Below is the layout file for the row, R.layout.adapters_tablelikelistview:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/data1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/data2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/data3"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/data4"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:layout_weight="1" />

</LinearLayout>

and the Activity and adapter where the layout above is used:

public class TableLikeListView extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);     
        String[] data1 = new String[] { "Header1", "data1", "data2" };
        String[] data2 = new String[] { "Header2", "data1", "data2" };
        String[] data3 = new String[] { "Header3", "data1", "data2" };
        String[] data4 = new String[] { "Header4", "data1", "data2" };
        setListAdapter(new MyAdapter(this, R.layout.adapters_tablelikelistview,
                R.id.data1, data1, data2, data3, data4));
    }

    private static class MyAdapter extends ArrayAdapter<String> {

        private String[] data1, data2, data3, data4;

        public MyAdapter(Context context, int resource, int textViewResourceId,
                String[] data1, String[] data2, String[] data3, String[] data4) {
            super(context, resource, textViewResourceId, data1);
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
            this.data4 = data4;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = super.getView(position, convertView, parent);
            if (position == 0) {
                // header
                v.setBackgroundColor(Color.GREEN);
            } else {
                v.setBackgroundResource(android.R.drawable.list_selector_background);
            }
            TextView t1 = (TextView) v.findViewById(R.id.data1);
            t1.setText(data1[position]);
            TextView t2 = (TextView) v.findViewById(R.id.data2);
            t2.setText(data2[position]);
            TextView t3 = (TextView) v.findViewById(R.id.data3);
            t3.setText(data3[position]);
            TextView t4 = (TextView) v.findViewById(R.id.data4);
            t4.setText(data4[position]);
            return v;
        }

        @Override
        public boolean isEnabled(int position) {        
            return position == 0 ? false : true;
        }       

    }

}
user
  • 86,916
  • 18
  • 197
  • 190
  • This works perfectly, only issue is that when I implement it into by layout with various other buttons and textviews, the data shown seems to break. I had to add into my xml. Any ideas why this would be happening? – SingleWave Games Nov 21 '12 at 17:42
  • @LandLPartners In my example I'm extending the `ListActivity`(for simplicity) which needs a `ListView` with that id. Regarding your layout breaking, I can't say anything without seeing what exactly are you doing there. Post the layout file or a description of it? – user Nov 21 '12 at 17:44
  • In regards to the above snippet, as my data is dynamic I am trying to use ArrayLists, however this is causing a casting issue within the XML Linear Layout. Do you know how i can solve this? Thanks – SingleWave Games Nov 22 '12 at 12:44
  • @LandLPartners I don't see where would a cast exception appear in the layout. Post the exception you get somewhere, like pastebin, gist and give me the link so I can have a look at it. – user Nov 22 '12 at 12:49
  • I have added my edited code and error message within patebin (http://pastebin.com/4FWTgnuZ). The only differene within my layout xml is that I have added a ListView, within my main class layout which implements your above xml code. Thanks – SingleWave Games Nov 22 '12 at 13:00
  • 1
    @LandLPartners There is another difference that throws that exception, the `Toast` that you used at the end of the `getView` method. My row layout file(I'm guessing this is what you use) has as its root a `LinearLayout`(wrapping all the four `TextViews`), but in that `Toast` object you try to cast it as a `TextView` to use `getText()`. Don't do this. – user Nov 22 '12 at 13:07
  • That was indeed the issue. Thanks for getting back to me so quickly – SingleWave Games Nov 22 '12 at 13:09
  • @Luksporg, I am trying to get the selected row to highlight and using the following code to do so: ListView list = getListView(); list.setChoiceMode(ListView.CHOICE_MODE_SINGLE); list.setSelector(R.drawable.selector); However, on click this is returning nothing without any errors, am i missing something? Thanks – SingleWave Games Nov 23 '12 at 17:55
  • 1
    @LandLPartners Your selector is probably drawn below the `TextViews`. See, if setting `drawSelectorOnTop` to `true` on your `ListView`, helps. Also check this link http://android.cyrilmottier.com/?p=454 , it has an explanation regarding this behavior. – user Nov 23 '12 at 18:03
  • Thank to your help I essentially have this working as it should. The only issue I had with your code was getting the position the user had clicked on outside of the Adapter. Therefore, I implemented an OnClickListener() within the Adapter. The issue here is that this override the highlighting of rows, do you know how i can stop this or an alternative way to get the selected rows position, outside of the Adapter. Thanks. – SingleWave Games Nov 29 '12 at 16:09
  • @LandLPartners First of all you should really post a new question, the comments area is more for clarification not to ask new questions. Second, I'm not sure I understand the problem especially *getting the position the user had clicked on outside of the Adapter*. A `ListView` has its own `OnItemClickListener` that you should use. – user Nov 29 '12 at 18:35