I have a ListView which is populated using a SimpleCursorAdapter. The row layout is given below:
<?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" >
<TextView
android:id="#+id/row"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp" />
<ImageView
android:id="#+id/enable_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:padding="10dp"
android:contentDescription="#string/image_description"
android:src="#android:drawable/checkbox_off_background" />
</RelativeLayout>
What i want to do is to change the source of the imageview to something else based on some shared preference when the activity is created. This is the code that i use but it doesn't work:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
long appliedProfileId = prefs.getLong("appliedProfileId", -1);
if(appliedProfileId != -1) {
/*View rowView = (View) getListView().getAdapter().getView(info.psition, null, null);
TextView textView = (TextView) rowView.findViewById(R.id.row);*/
ListView listView = getListView();
ListAdapter adapter = listView.getAdapter();
View appliedRowLayout = (View) adapter.getView(getItemPositionByAdapterId(adapter, appliedProfileId), null, null);
TextView textView = (TextView) appliedRowLayout.findViewById(R.id.row);
Log.d("asdasd", textView.getText().toString());
ImageView imageView = (ImageView) appliedRowLayout.findViewById(R.id.enable_image);
imageView.setImageResource(android.R.drawable.checkbox_on_background);
setListAdapter(adapter);
}
This is the getItemPositionByAdapterId method:
private int getItemPositionByAdapterId(ListAdapter adapter, final long id)
{
for (int i = 0; i < adapter.getCount(); i++)
{
if (adapter.getItemId(i) == id)
return i;
}
return -1;
}
I am able to read the contents of the listview but cannot change them.. Pleas help :)
You need to override the getView method for this listview. Check Customizing Android ListView Items
You need to do something like this.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (position == 0) // first element in the list
{
convertView.findViewById(R.id.image1).setImageURI(....)
}
and so on....
Related
I have a couple of AutocompleteTextView as items in ListView; these items are dynamically loaded using Custom adapter. When an item is selected in the AutoCompleteTextView, I need to update another TextView which is on the same row as the AutoCompleteTextView. I'm having trouble identifying position of AutoCompleteTextView where an item was selected. Any pointers would be appreciated:
My Activity looks like this, where Listview is defined:
<ListView
android:id="#+id/listview_orders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
ListView Items are defined in another layout file as:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<AutoCompleteTextView
android:id="#+id/product_code_row_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:ems="10" />
<AutoCompleteTextView android:id="#+id/product_name_row_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
/>
<TextView android:id="#+id/product_size_row_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
/>
</LinearLayout>
ListView adapter is being set as below:
ListView view = (ListView) findViewById(R.id.listview_orders);
ListViewItemAdapter adapter = new ListViewItemAdapter(this, orderItems, prodCodeList, prodNameList);
view.setAdapter(adapter);
Custom Adapter getView method implementation is as follows:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = activity.getLayoutInflater();
convertView = inflater.inflate(R.layout.order_list_row, null);
}
AutoCompleteTextView productCode = (AutoCompleteTextView ) convertView.findViewById(R.id.product_code_row_item);
AutoCompleteTextView productName = (AutoCompleteTextView) convertView.findViewById(R.id.product_name_row_item);
TextView productSize = (TextView) convertView.findViewById(R.id.product_size_row_item);
TextView mQty = (TextView) convertView.findViewById(R.id.product_mqty_row_item);
OrderItem orderItem = (OrderItem)orderItemList.get(position);
productCode.setText(orderItem.getProductCode());
productCode.setTag(position);
productName.setText(orderItem.getDescription());
productName.setTag(position);
productSize.setText(orderItem.getProductSize());
//Setting up autocorrect adapter for product codes
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(activity, android.R.layout.select_dialog_item, prodCodeList);
//Getting the instance of AutoCompleteTextView
productCode.setThreshold(1);//will start working from first character
productCode.setAdapter(adapter);//setting the adapter data into the AutoCompleteTextView
productCode.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View arg1, int pos,
long id) {
Toast.makeText(OrderApplication.getCustomAppContext(), (CharSequence)parent.getItemAtPosition(pos), Toast.LENGTH_LONG).show();
int itemPosition = (Integer) arg1.getTag();
//loadOrderItem(newOrderItem, (String) parent.getItemAtPosition(pos), true);
}
});
//Setting up autocorrect adapter for product names
adapter = new ArrayAdapter<String>
(activity, android.R.layout.select_dialog_item, prodNameList);
//Getting the instance of AutoCompleteTextView
productName.setThreshold(2);//will start working from first character
productName.setAdapter(adapter);//setting the adapter data into the AutoCompleteTextView
return convertView;
}
you should use -
adapter.getItem(pos)
inside your onItemClick
I found a workaround to get reference of AutoCompleteTextView in listview.
holder.productCodeView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
currentFocusView = v;
}
}
});
holder.productCodeView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View arg1, int pos, long id) {
if (currentFocusView != null) {
int iPosition = (Integer) currentFocusView.getTag();
}
}
});
Hi guys I am new to Android and also to stackoverflow, Greetings and thanks for the help.
I have 2 Xml files for the same activity. One that contains a ListView and the second as my custom layout for an ArrayAdapter that populates a ListView which is also included on my first layout:
<include android:id="#+id/lv" layout="#layout/lv_row" />
ListView Custom Layout (lv_row.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/icon"
android:src="#drawable/ic_launcher"/>
<TextView
android:layout_toRightOf="#+id/icon"
android:layout_width="fill_parent"
android:layout_height="38dp"
android:textSize="30sp"
android:id="#+id/label"/>
<TextView
android:layout_toRightOf="#+id/icon"
android:layout_below="#+id/label"
android:layout_width="fill_parent"
android:layout_height="12dp"
android:gravity="bottom"
android:id="#+id/label2"
android:textSize="12sp"/>
</RelativeLayout>
This is my adapter:
final ArrayAdapter<String> Array = new ArrayAdapter<String>(this,R.layout.lv_row,R.id.label,myList);
I save strings one by one into "myList" and display them on my ListView, what I want to do is to enumerate the elements on my list view by using idNum.setText(iterating_variable.toString())... but it won't work because idNum always get the value that was set on the XML file.
This is the code I use to link the second XML with my Java code
lv = (RelativeLayout) findViewById(R.id.lv);
idNum = (TextView) lv.findViewById(R.id.label2);
Thanks again for your help.
create custom Adapter and setText() in getView() method of adapter
like
class CustomAdapter extends BaseAdapter {
private ArrayList<String> mList;
private LayoutInflater mInflater;
public CustomAdapter(ArrayList<String> list) {
mList = list;
mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mList.size() ;
}
#Override
public Object getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = mInflater.inflate(R.layout.lv_row, null);
((TextView) convertView.findViewById(R.id.label2)).setText(mList.get(position));
return convertView;
}
}
and set on ListView
I have created a custom listview and a custom adapter. However, when I show the activity it appears empty (although I made sure and there are people in the array passed to the adapter).
1) Why won't it show the people list? Is there something wrong in my getView or in my onCreate function?
2) How can I make a list view that is surrounded by another view (searchbar on top list at the bottom)?
Here is the adapters getView function:
#Override
public View getView(int postion, View convertView, ViewGroup parent)
{
View rowView = convertView;
if (rowView == null)//set the convert view and the viewholder
{
LayoutInflater inflater = _context.getLayoutInflater();
rowView = inflater.inflate(_layoutResourceId, null,false);
ViewHolder viewHolder = new ViewHolder();
viewHolder._personName = (LargeTest) rowView.findViewById(R.id.personName);
viewHolder._personBirthDate = (TextView) rowView.findViewById(R.id.personBirthDate);
viewHolder._icon = (ImageView) rowView.findViewById(R.id.personPic);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
Person person=_persons.get(postion);//get current person for the list row
String personName = person.get_firstName()+" "+person.get_lastName();
((TextView) holder._personName).setText(personName);
String birthDate=person.get_birthDate()+";"+person.get_hebBirthDate();
holder._personBirthDate.setText(birthDate);
//TODO change icon to a real image for each Person
holder._icon.setImageResource(R.drawable.about_me);//test icon
return rowView;
}
Here is the listview onCreate function:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//TODO remove the test case
//addTestPersons();//add a test case
//setContentView(R.layout.person_list_activity);
PersonDbHelper dbHelper=new PersonDbHelper(this);
ArrayList<Person> persons =dbHelper.getAllPeopleAsPersonList();//get list to display
PersonListAdapter adapter=new PersonListAdapter(this, R.layout.person_list_row, persons);
setListAdapter(adapter);
}
And the XML for list_row:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="#+id/personPic"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/about_me" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/personName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Person Name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/personBirthDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1990-2001" />
</LinearLayout>
</LinearLayout>
Implement the getCount method in the adapter:
public int getCount(){
return _persons.size();
}
For the second part, add the headerview, create an XML layout for the view that you want to show on top of listview. Inflate it and add as headerview to your listview:
LayoutInflater inflater = this.getLayoutInflater();
View headerView = inflater.inflate(R.layout.header_view, null,false);
getListView().addHeaderView(headerView,null,false);
Because of the naming of the layout, you are passing "R.layout.person_list_row" to your adapter. I assume that you are passing the layout for one item in the array on which the adapter operates on instead of passing the ListView.
The constructor needs the ListView to be passed while in its getView, the layout for the row is constructed (inflated).
I have list view:
<ListView android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
And I add some items to it:
final ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < items.length(); ++i) {
try {
list.add(items[i].getString("title"));
} catch (JSONException e) {
e.printStackTrace();
}
}
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
listview.setAdapter(adapter);
But now I want to add some TextViews (at example if(i==5)) to the list, like a label. It should not be clickable.
How can I add it?
listview.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2,long arg3)
{
long pos = arg0.getItemIdAtPosition(arg2);
if(pos != 5)
{
//add textview
}
else
{
//nothing
}
}
});
You should use a custom row layout instead of android.R.layout.simple_list_item_1, for example a row.xml you have one text view whose visibility is set to gone by default:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/nonclickable_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/normal_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Put it in res/layout/ folder, then call R.layout.row instead of android.R.layout.simple_list_item_1 when you create your StableArrayAdapter. In the getView() method
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView==null) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row, parent,false);
}
if(int position==5) {
TextView tv = (TextView)convertView.findViewById(R.id.nonclickable_text);
tv.setVisibility(View.VISIBLE);
}
I want the onclick method to communicate with the other views in my layout. I am getting a NullPointerException when attempting to do so. I think I may be doing it wrong.
My getView method is below:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
final int p =position;
if (v == null) {
LayoutInflater vi = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.menuitemrow, null);
holder = new ViewHolder();
holder.image = (ImageView) v.findViewById(R.id.MIR_itemImage);holder.image.setTag(position);
holder.itemName = (TextView)v.findViewById(R.id.MIR_itemName);holder.itemName.setTag(position);
holder.itemPrice = (TextView)v.findViewById(R.id.MIR_itemPrice);holder.itemPrice.setTag(position);
holder.itemOther = (TextView)v.findViewById(R.id.MIR_itemOther);holder.itemOther.setTag(position);
holder.details = (Button) v.findViewById(R.id.MIR_detailsbtn);holder.details.setTag(position);
holder.qAdd = (Button) v.findViewById(R.id.MIR_qaddbtn);holder.qAdd.setTag(position);
v.setTag(holder);
} else
holder = (ViewHolder) v.getTag();
MenuItemDetail mid = _data.get(position);
holder.image.setImageResource(mid.icon);
holder.itemName.setText(mid.itemName);
holder.itemPrice.setText("Price: $"+mid.itemPrice);
holder.itemOther.setText(mid.itemOther);
//set click listeners
holder.details.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
m =_data.get(p);
s = m.getItemName();
Toast.makeText(_c, "clicked details"+p+" "+s, Toast.LENGTH_SHORT).show();
}
});
holder.qAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(_c, "clicked quick add "+p, Toast.LENGTH_SHORT).show();
TextView btnUpdate = (TextView) v.findViewById(R.id.CBV_textview2);
//btnUpdate.setTag(1);
//btnUpdate.setText(btnUpdate.getTag().toString());
btnUpdate.setText("b");
}
});
return v;
}
as you can see I am just assigning a number to the getTag just to pass it to the setText method. I have tried it commenting out the set and get, using just a String.
the problematic line is btnUpdate.setText("b");
Any ideas?
to summarize I am trying to access a TextView of a custom Button inside of a custom ListView from its customer adapter's getView method.
UPDATE for comment:
This is a Custom Listview being displayed with other buttons. I want the listview item (a button that is part of the custom ListView) when it is click to update the textview of a custom button I created that is displayed in the same acitivity as the custom list view.
The Layout is below:
<?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" >
<Button
android:id="#+id/MI_backbutton"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_weight="1"
android:text="#string/back_list_categories"
android:textSize="#dimen/FontSize8" />
<ListView
android:id="#+id/menuList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="20" >
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom"
android:layout_marginBottom="5dp"
android:layout_weight="1" >
<Button
android:id="#+id/button2"
style="#android:style/Widget.Button"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="bottom"
android:layout_weight="1"
android:text="#string/generalbutton" />
<include
android:id="#+id/MI_checkorder"
style="android:buttonStyle"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="bottom"
android:layout_marginTop="5dp"
android:layout_weight="1"
layout="#layout/custombtnview"
android:background="#style/AppTheme"
android:clickable="true"
android:focusable="true" />
</LinearLayout>
In the view I am referencing to get the Textview, the textview is not there. What is in that view is the MI_checkorder. I was thinking maybe this is why I am getting the NullPointerException for my btnUpdate. the textveiw CBV_textview2 is part of the view I created as a button(MI_checkorder).
I now have the button but I am unable to get the change to show on the UI. Here is the code I added:
public void onClick(View v) {
Toast.makeText(_c, "clicked quick add "+p, Toast.LENGTH_SHORT).show();
TextView btnUpdate = (TextView) inflateToEdit(_c, v).findViewById(R.id.CBV_textview2);
//btnUpdate.setTag(1);
//btnUpdate.setText(btnUpdate.getTag().toString());
btnUpdate.setText("b");
}
and this is the method I created in the custom adapter class.
public View inflateToEdit(Context c, View view){
View vw = view;
LayoutInflater vi = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return vi.inflate(R.layout.custombtnview, null);
}
It is updating the button's text but it is not showing on the UI. I do not think i can update the UI from this point in the code. I think I need to do it from the activity.
That's because findViewById called on a view looks for the child view of the given view.
findViewById doc
"Look for a child view with the given id. If this view has the given id, return this view."
From what I can see, CBV_textview2 is contained in the layout of the activity.
So, what you can do is to pass the activity to the adapter's constructor (I see you already have a _c member variable which I suppose is a Context, OR directly pass the CBV_textview2 itself (calling findViewById in the containing activty).
In both cases, you need to call the activity's findViewById which
"Finds a view that was identified by the id attribute from the XML that was processed in onCreate(Bundle)."
public class YourAdapter extends ArrayAdapter<String> {
private final Context context;
// blahblahblah
private final TextView mYourTextView;
public YourAdapter(Context context, String[] values, TextView btnUpdate) {
super(context, R.layout.rowlayout, values);
this.context = context;
this.values = values;
mYourTextView = btnUpdate;
}
....
#Override
public void onClick(View v) {
Toast.makeText(_c, "clicked quick add "+p, Toast.LENGTH_SHORT).show();
//mYourTextView.setTag(1);
//mYourTextView.setText(btnUpdate.getTag().toString());
mYourTextView.setText("b");
}
In your activity you should be able to get the TextView before calling the constructor.