I am new to the android api and I have some problems with .. the basics.
I'm trying to get a list working, but the list displays the wrong text:
Each row has two TextViews (title, subtitle), heres the xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<TextView
android:id="#+id/row_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TITLE"
android:textSize="15dip"
android:layout_gravity="center_vertical" />
<TextView
android:id="#+id/row_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/row_title"
android:text="SUBTITLE"
android:textSize="10dip"
android:layout_gravity="center_vertical" />
</RelativeLayout>
I extend ListFragment (I need this fragment thing, because of a slidingMenu library), have a custom adapter and an item class.
in the onActivityCreated() method I add some random items to the adapter:
package com.slidingmenu.example;
import android.app.Fragment;
import android.app.ListFragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class SampleListFragment extends ListFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.list, null);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
SampleAdapter adapter = new SampleAdapter(getActivity());
for (int i = 0; i < 20; i++) {
adapter.add(new SampleItem(new Fragment(), "title no. " + i, "some subtitle"));
}
setListAdapter(adapter);
}
private class SampleItem {
public Fragment frag;
public String title;
public String subTitle;
public SampleItem(Fragment frag, String title, String subTitle) {
this.frag = frag;
this.title = title;
this.subTitle = subTitle;
}
}
public class SampleAdapter extends ArrayAdapter<SampleItem> {
public SampleAdapter(Context context) {
super(context, 0);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, null);
}
TextView title = (TextView) convertView.findViewById(R.id.row_title);
TextView subTitle = (TextView) convertView.findViewById(R.id.row_subtitle);
return convertView;
}
}
}
So I thougt that the list would display something like this:
title no. 0
some subtitle
-
title no. 1
some subtitle
-
title no. 2
some subtitle
-
etc.
but instead it just displays what I defined in the row.xml:
TITLE
SUBTITLE
-
TITLE
SUBTITLE
-
etc.
I think getView() needs to be changed (at least it doesn't make to much sense to me) but I'm not sure.
Everything I try results in some nullpointer exception or worse.
Please, can someone tell me what I need to change?
The error is int the Adapter:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, null);
}
TextView title = (TextView) convertView.findViewById(R.id.row_title);
TextView subTitle = (TextView) convertView.findViewById(R.id.row_subtitle);
return convertView;
}
the getView never fills up the title and subtitle. Second you never submit to the superclass the dataset you want to show in the ListFragment.
Here you have to ways. Or you ovveride the getCount and getItem and getItemId methods, or feed up the superclass with the dataset, using this constructor. Read carefully the documentation.
Related
I am using ListView with ArrayAdapter and trying to add fragments to all rows of the ListView. However, the app does not work correctly: only one row on the screen showed with the added fragment but not all rows. Sometimes the app may be crashed because out of memory.
Can someone give me some advices? Thanks.
MainActivity.java
package com.me.test05;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
ListView myListView = (ListView) findViewById(R.id.myListView);
myListView.setAdapter(new MyArrayAdaptor(this, R.layout.row));
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
private static final String[] allnames = { "John", "Marry", "Smith", "Felicity", "Lion", "Math" };
public static class MyArrayAdaptor extends ArrayAdapter<String> {
private final Context context;
public MyArrayAdaptor(Context context, int resource) {
super(context, resource);
this.context = context;
}
#Override
public int getCount() {
return allnames.length * 100;
}
#Override
public String getItem(int position) {
return allnames[position % allnames.length];
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.row, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.textView1);
String str = getItem(position);
textView.setText(str);
FragmentTransaction ft = ((Activity) context).getFragmentManager().beginTransaction();
ft.replace(R.id.myFrameLayout, new PlaceholderFragment());
ft.commit();
return rowView;
}
}
}
File activity.xml:
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:fitsSystemWindows="true">
<ListView android:id="#+id/myListView"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:dividerHeight="2px">
</ListView>
</merge>
File row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="abc" />
<FrameLayout
android:id="#+id/myFrameLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</FrameLayout>
</LinearLayout>
File fragment_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/textView1"
android:text="Button" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</LinearLayout>
Screen looks like:
I have solved that problem. The problem is the fragment manager always find (to replace by a new fragment) an id in global. That is why it always found and added all new fragments into the first row since it is the first one contains that id (as well as all other rows).
To solve the problem, I create dynamic ids which are unique for each row then replace that fixed id by them before letting fragment manager to do the rest. I also store those dynamic ids into rows' tags to reuse latter.
The new code is bellow, including the code for finding and reusing added fragments:
package com.me.test05;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
ListView myListView = (ListView) findViewById(R.id.myListView);
myListView.setAdapter(new MyArrayAdaptor(this, R.layout.row));
}
}
public static class PlaceholderFragment extends Fragment {
private View rootView = null;
private String theString = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main, container, false);
setString(theString);
return rootView;
}
public void setString(String str) {
theString = str;
if (theString != null && rootView != null) {
TextView textView = (TextView) rootView.findViewById(R.id.textView2);
textView.setText(str);
}
}
}
private static final String[] allnames = { "John", "Marry", "Smith", "Felicity", "Lion", "Math" };
public static class MyArrayAdaptor extends ArrayAdapter<String> {
private final Context context;
public MyArrayAdaptor(Context context, int resource) {
super(context, resource);
this.context = context;
}
#Override
public int getCount() {
return allnames.length * 100;
}
#Override
public String getItem(int position) {
return allnames[position % allnames.length];
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = convertView;
PlaceholderFragment myFragment = null;
if (rowView == null) {
rowView = inflater.inflate(R.layout.row, parent, false);
int newId = 100000 + position;
FrameLayout layout = (FrameLayout) rowView.findViewById(R.id.myFrameLayout);
layout.setId(newId);
rowView.setTag(newId);
myFragment = new PlaceholderFragment();
FragmentTransaction ft = ((Activity) context).getFragmentManager().beginTransaction();
ft.replace(newId, myFragment, "" + newId).commit();
} else {
Integer theId = (Integer) convertView.getTag();
myFragment = (PlaceholderFragment) ((Activity) context).getFragmentManager().findFragmentById(theId);
}
String str = getItem(position);
myFragment.setString(str + ", " + position);
TextView textView = (TextView) rowView.findViewById(R.id.textView1);
textView.setText(str);
return rowView;
}
}
}
I followed all the steps from various sources for getting listviews to work but my one
doesn't seem to display anything. This list view code(shown below) is activated with a tab fragment manager I won't put that here as to not bog you all down with code as there's a lot here already. It is most likely a problem with the ListFragment itself but I suppose it could be the adapter.
What happens is nothing gets displayed at all just the searchview that I have put in the main xml layout. I can switch freely between tabs with no crashes but just nothing displays in any of my listviews. I have another list which is a friends list(not included in this code snippet) and that uses a generic view holder interface and that one does not work either which suggests the problem is most likely in my ListFragment but I just can't pinpoint it. Any help is appreciated and I hope some can learn something from this, Thank you.
This is my adapter for the settings category list
package codeblox.com.listfragmentexample;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;
import java.util.ArrayList;
import codblox.com.listfragmentexample.R;
public class SettingsAdapter extends ArrayAdapter<Settings.SettingsCategories>
{
private final Activity context;
String[] text;
ArrayList<Settings.SettingsCategories> itemsCopy;
class ViewHolder
{
public TextView txt;
public CheckBox state;
public ImageView settingImg;
public EditText input;
public ToggleButton toggle;
public Button settingInfo; // click it to show what the setting does
}
public SettingsAdapter(Context context, ArrayList<Settings.SettingsCategories> items)
{
super(context, R.layout.settings_category_row, items);
this.context = (Activity) context;
this.itemsCopy = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = new ViewHolder();
int viewType = this.getItemViewType(position);
if(convertView == null)
{
// inflate the GridView item layout
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.settings_category_row, parent, false);
// initialize the view holder
holder = new ViewHolder();
holder.settingImg = (ImageView) convertView.findViewById(R.id.settingCategoryImg);
holder.txt = (TextView) convertView.findViewById(R.id.settingCategoryName);
convertView.setTag(holder);
} else {
// recycle the already inflated view
holder = (ViewHolder) convertView.getTag();
}
// fill data
holder = (ViewHolder) convertView.getTag();
String s = getItem(position).toString();
holder.txt.setText(itemsCopy.get(position).getSettingText());
holder.settingImg.setImageResource(itemsCopy.get(position).getImgResId());
return convertView;
}
}
This is my list fragment
package codeblox.com.listfragmentexample
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import codeblox.com.listfragmentexample.R;
public class Settings extends ListFragment implements View.OnLongClickListener
{
private ListView settingsList;
private ArrayList<SettingsCategories> mItems;
private ArrayAdapter<SettingsCategories> settingsAdapter;
private int numCategories;
String[] CategoryArray = new String[] {"Privacy and Security","Account","Networks","Camera Options","Storage","Accesibility","Features"};
int[] resIds = new int[] {R.drawable.security_settings_icon,R.drawable.account_settings_icon,
R.drawable.network_settings_icon,R.drawable.camera_settings_icon,R.drawable.storage_settings_icon,
R.drawable.accessibility_settings_icon,R.drawable.feature_settings_icon,};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View settingsView = inflater.inflate(R.layout.settings, container, false);
settingsList = (ListView)settingsView.findViewById(android.R.id.list);
// initialize the items list
return settingsView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
// remove the dividers from the ListView of the ListFragment
settingsList = getListView();
settingsList.setDivider(null);
mItems = new ArrayList<SettingsCategories>();
Resources resources = getResources();
for(int c = 0; c < numCategories; c++)
{
mItems.add(new SettingsCategories(CategoryArray[c],resIds[c]));
}
// initialize and set the list adapter
// settingsAdapter = new SettingsAdapter(this.getActivity(), mItems);
setListAdapter(new SettingsAdapter(getActivity(), mItems));
settingsList.setAdapter(settingsAdapter);
}
public Settings()
{
this.numCategories = CategoryArray.length;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public boolean onLongClick(View v)
{
return false;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
Object i = l.getItemAtPosition(position);
}
public class SettingsCategories
{
private String settingText;
private int imgResId;
SettingsCategories(String settingText,int imgResId)
{
this.settingText = settingText;
this.imgResId = imgResId;
}
public String getSettingText()
{
return this.settingText;
}
public int getImgResId()
{
return this.imgResId;
}
}
}
and finally these are my xml layouts (the first one is the main view and the second one is the view of a single item in the list
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<SearchView
android:id="#+id/searchFunction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</SearchView>
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</RelativeLayout>
this represents an individual item in the list
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="52dp"
android:layout_height="52dp"
android:id="#+id/settingCategoryImg"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="52dp"
android:text=""
android:id="#+id/settingCategoryName"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/settingCategoryImg"
/>
</RelativeLayout>
You are setting null adapter so it is not refreshing.
you are commented initialization part
check in the following method:
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
// remove the dividers from the ListView of the ListFragment
settingsList = getListView();
settingsList.setDivider(null);
mItems = new ArrayList<SettingsCategories>();
Resources resources = getResources();
for(int c = 0; c < numCategories; c++)
{
mItems.add(new SettingsCategories(CategoryArray[c],resIds[c]));
}
// initialize and set the list adapter
// settingsAdapter = new SettingsAdapter(this.getActivity(), mItems);
setListAdapter(new SettingsAdapter(getActivity(), mItems));
settingsList.setAdapter(settingsAdapter);
}
Your are using ListFragement and again inflating layout. that is not a good idea. when you are extending listfragment then inflating the layout is not required and and modify above method like:
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
// remove the dividers from the ListView of the ListFragment
settingsList = getListView();
settingsList.setDivider(null);
mItems = new ArrayList<SettingsCategories>();
Resources resources = getResources();
for(int c = 0; c < numCategories; c++)
{
mItems.add(new SettingsCategories(CategoryArray[c],resIds[c]));
}
// initialize and set the list adapter
settingsAdapter = new SettingsAdapter(this.getActivity(), mItems);
//setListAdapter(new SettingsAdapter(getActivity(), mItems));
settingsList.setAdapter(settingsAdapter);
}
I have a custom ArrayAdapter which contains a text and an image, but somehow the items don't show in the list.
This is my custom adapter:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class DrawerArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] entries;
private final Integer[] imageIds;
public DrawerArrayAdapter(Context context, String[] entries, Integer[] imageIds) {
super(context, R.layout.drawer_list_item, entries);
this.context = context;
this.entries = entries;
this.imageIds = imageIds;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.drawer_list_item, parent, false);
TextView entryView = (TextView) rowView.findViewById(R.id.drawer_list_entry);
ImageView iconView = (ImageView) rowView.findViewById(R.id.drawer_list_icon);
entryView.setText(entries[position]);
iconView.setImageResource(imageIds[position]);
return rowView;
}
}
And this is the Fragment:
import android.app.ListFragment;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class DrawerFragment extends ListFragment {
private String[] drawerListEntries;
private DrawerLayout drawerLayout;
private Integer[] drawerListIcons;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawerListIcons = new Integer[] {R.drawable.ic_action_user,R.drawable.ic_action_user,R.drawable.ic_action_user,R.drawable.ic_action_user};
drawerListEntries = getResources().getStringArray(R.array.drawer_items);
setListAdapter(new DrawerArrayAdapter(getActivity(), drawerListEntries, drawerListIcons));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.drawer_fragment, container, false);
}
#Override
public void onStart() {
super.onStart();
drawerLayout = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(),
getListView().getItemAtPosition(position).toString(),
Toast.LENGTH_LONG).show();
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
//boolean drawerOpen = drawerLayout.isDrawerOpen(drawerList);
//menu.findItem(R.id.action_user).setVisible(!drawerOpen);
super.onPrepareOptionsMenu(menu);
}
}
and this is my drawer_list_item.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="70dp"
android:padding="5dp"
android:orientation="vertical" >
<TextView
android:id="#+id/drawer_list_entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="12dp"
android:paddingLeft="20dp"
android:paddingBottom="20dp"
android:paddingTop="20dp"
android:textSize="24sp"
android:textColor="#color/light_blue"
android:fontFamily="sans-serif-light" >
</TextView>
<ImageView
android:id="#+id/drawer_list_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/drawer_icon">
</ImageView>
</LinearLayout>
I should probably mention that when I just use a normal ArrayAdapter with just text, it works perfectly. Anyone seeing the problem?
You really don't want to inflate new views for every row in your custom adapter's getView() ignoring the provided convertView. ListViews don't use 1000 separate views when you have 1000 rows in the adapter, views get recycled.
So I would simply call:
View view = super.getView(position, convertView, parent);
and then use view.findViewById() to set the data on your individual sub-views before returning the view that the ArrayAdapter returned. The ArrayAdapter already takes care of re-using recycled views.
Note that ArrayAdapter already sets the TextView itself, so you only need to set the ImageView, but for that the ArrayAdapter will need to know the id of your TextView, so use the constructor:
super(context, R.layout.drawer_list_item, R.id.drawer_list_entry, entries);
Because views are recycled make sure to always set the ImageView source. If a particular row has no image you need to clear it rather than do nothing.
EDIT: Another problem was related to the row layout. The vertical margin and padding was too much for the limited vertical row height of 70dp.
EDIT: Here an example of the adapter.
public class DrawerArrayAdapter extends ArrayAdapter<String> {
private final Integer[] mImageIds;
public DrawerArrayAdapter(Context context, String[] entries, Integer[] imageIds) {
super(context, R.layout.drawer_list_item, R.id.drawer_list_entry, entries);
mImageIds = imageIds;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = super.getView(position, convertView, parent);
((ImageView)rowView.findViewById(R.id.drawer_list_icon)).setImageResource(mImageIds[position]);
return rowView;
}
}
Some suggestions here.
1) Extend BaseAdapter instead of ArrayAdapter.
2) implement getCount method of base adapter and return list.size as return value(integer). here list can be your arrays length.
In My application i customized gridview to show header and subitems. But i can't select individual items. My codes as follows
main_activity
public class MainActivity extends Activity {
private TextView tv;
private GridView gv;
private GridAdapter ga;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.TextMsg);
gv = (GridView)findViewById(R.id.gridView);
ga = new GridAdapter(this);
gv.setAdapter(ga);
GridAdapter.Item item = new GridAdapter.Item();
item.set("Header1", "Item1_1", "Item1_2", "Item1_3");
ga.add(item);
item = new GridAdapter.Item();
item.set("Header2", "Item2_1", "Item2_2", "Item2_3");
ga.add(item);
item = new GridAdapter.Item();
item.set("Header3", "Item3_1", "Item3_2", "Item3_3");
ga.add(item);
}
}
GridAdapter.java
package com.example.testapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class GridAdapter extends ArrayAdapter<GridAdapter.Item> {
private LayoutInflater m_vi = null;
private GridAdapter.Item m_item = null;
private ViewHolderItem m_holderItem = null;
public GridAdapter(Context context) {
super(context, 0);
m_vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
m_item = (GridAdapter.Item)getItem(position);
if (convertView == null || !convertView.getTag().equals(m_holderItem)){
convertView = m_vi.inflate(R.layout.mygrid, null);
m_holderItem = new ViewHolderItem();
convertView.setTag(m_holderItem);
}
else {
m_holderItem = (ViewHolderItem) convertView.getTag();
}
m_holderItem.tvHeader = (TextView)convertView.findViewById(R.id.gridhead);
m_holderItem.tvItem1 = (TextView) convertView.findViewById(R.id.gridtext1);
m_holderItem.tvItem2 = (TextView) convertView.findViewById(R.id.gridtext2);
m_holderItem.tvItem3 = (TextView) convertView.findViewById(R.id.gridtext3);
m_holderItem.tvHeader.setText(m_item.getHeader());
m_holderItem.tvItem1.setText(m_item.getItem1());
m_holderItem.tvItem2.setText(m_item.getItem2());
m_holderItem.tvItem3.setText(m_item.getItem3());
return convertView;
}
public static class ViewHolderItem {
public TextView tvHeader;
public TextView tvItem1;
public TextView tvItem2;
public TextView tvItem3;
}
public static class Item {
public String Header, Item1, Item2, Item3;
public Item(){
this.Header = "";
this.Item1 = "";
this.Item2 = "";
this.Item3 = "";
}
public void set(String Header_i, String Item1_i, String Item2_i, String Item3_i) {
this.Header = Header_i;
this.Item1 = Item1_i;
this.Item2 = Item2_i;
this.Item3 = Item3_i;
}
public String getHeader(){
return this.Header;
}
public String getItem1(){
return this.Item1;
}
public String getItem2(){
return this.Item2;
}
public String getItem3(){
return this.Item3;
}
}
}
mygrid-xml
<?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="vertical">
<TextView
android:id="#+id/gridhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/gridtext1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:layout_width="20dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/gridtext2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:layout_width="20dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/gridtext3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<View
android:layout_width="wrap_content"
android:layout_height="5dp"
/>
</LinearLayout>
present image;
i just want o/p like just below
Select only item2-2
Since the items you want selected are not distinct gridview items, but children of gridview items, I believe your only option is to set the onClickListeners for each of the textViews you add in the getView method, and write your own code for coloring the background of the "selected" textview, returning the previous textview to normal color, etc.
It also requires a fairly good understanding of how adapter views are recycled, and such.
Edit: A rough outline how to accomplish this:
It is a bit of an undertaking. The best I can post for you is a good outline:
setOnClickListener for each View you hope to capture a click. These will be the particular TextViews you add in the GetView method.
Do whatever you want to graphically indicate the view is selected. (e.g. yellow background).
Record the position of the selected view.
Find previous selected View, and remove graphical selection, if needed.
Because views get recycled, whatever you do graphically for the "selected" view, may start appearing on other views as you scroll, if the graphical elements are not checked and removed everytime getView is called; they will also need to be reapplied when the user scrolls back.
I want to have a list of elements (using a ListView) and each element in list is styled with a relative layout. Currently, the items are being displayed correctly, however, for some reason the listview items dont glow green when they're clicked. Why is this?
I have removed all code to minimals and it still does this.
Activity class
package com.test;
import android.app.Activity;
public class My_ListView extends Activity
{
private ListView_Adapter listViewAdapter;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.my_listview);
// initialise the list-view object
listViewAdapter = new ListView_Adapter(this);
listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(listViewAdapter);
for (int i=0;i<20;i++)
{
listViewAdapter.add("item "+i);
}
}
public void clicked(View v)
{
v.setBackgroundColor(0xFF0000FF);
}
}
The listview item adapter class
package com.test;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class ListView_Adapter extends ArrayAdapter<String>
{
public ListView_Adapter(Context c)
{
super(c, R.layout.my_listview_item);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
StationFinder_ListViewItemHolder holder = null;
if (row == null)
{
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.my_listview_item, parent, false);
holder = new StationFinder_ListViewItemHolder(row);
row.setTag(holder);
}
else
{
holder = (StationFinder_ListViewItemHolder) row.getTag();
}
holder.populateFrom(getItem(position));
return row;
}
static class StationFinder_ListViewItemHolder
{
private TextView destination = null;
StationFinder_ListViewItemHolder(View row)
{
destination = (TextView) row.findViewById(R.id.text1);
}
void populateFrom(String locationDistance)
{
destination.setText(locationDistance);
}
}
}
my_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<ListView android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
my_listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="clicked"
>
<TextView android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
I think you may have to call invalidate() after setting the background color.
You may want to do this instead by setting the listSelector and possibly drawSelectorOnTop for your ListView. That way the selection/deselection and clicks will be handled in the normal manner.
Edit - also, since you're using a ListView, you probably want to listen for clicks by setting an OnItemClickListener on your ListView.