I am in Android Studio trying to implement a custom ListView. I have created an xml file called "custom_layout_rachel.xml" and have put it in my "layout" folder. This file contains the code for how I want my ListView to look.
I am trying to make the list view in my page called "activity_urgent__important.xml" to look like the one in "custom_layout_rachel.xml". In this file, I have the following code:
<ListView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#+id/lvItems"
tools:listitem="#layout/custom_layout_rachel"
/>
In Android Studio, the custom layout is showing up, but when I run the app on my emulator, it is not there.
The java code for this activity, looks like:
lvItems = (ListView) findViewById(R.id.lvItems);
items = new ArrayList<String>();
itemsAdapter = new ArrayAdapter<String>(this, android.R.layout.custom_layout_rachel, items);
lvItems.setAdapter(itemsAdapter);
on the third line is where my error is.
Does anyone know why I can't do this or why I am getting an error?
Thank you!!!
New:
lvItems = (ListView) findViewById(R.id.lvItems);
items = new ArrayList<String>();
readItems();
itemsAdapter = new CustomListAdapter(this, items);
lvItems.setAdapter(itemsAdapter);
Getting an error on "Custom List Adapter(this, items)
I do not have adapter code, but I did start the following, I could implement it if it would work:
public class CustomListAdapter extends ArrayAdapter {
private Context mContext;
private int id;
private List<String> items ;
public CustomListAdapter(Context context, int textViewResourceId , List<String> list )
{
super(context, textViewResourceId, list);
mContext = context;
id = textViewResourceId;
items = list ;
}
public CustomListAdapter(Context context , List<String> list) {
super(context, items);
}
#Override
public View getView(int position, View v, ViewGroup parent)
{
View mView = v ;
if(mView == null){
LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = vi.inflate(id, null);
}
TextView text = (TextView) mView.findViewById(R.id.textView);
if(items.get(position) != null )
{
text.setTextColor(Color.WHITE);
text.setText(items.get(position));
text.setBackgroundColor(Color.RED);
int color = Color.argb( 200, 255, 64, 64 );
text.setBackgroundColor( color );
}
return mView;
}
In your second CustomListAdapter constructor, initialize mContext and items since mContext will be used in inflating the view in getView() method.
public CustomListAdapter(Context context , List<String> list) {
super(context, items);
mContext = context;
items = list ;
}
If you are creating your own adpater extending String type. You don't have to pass android.R.layout.custom_layout_rachel in your third line of code.
You will be inflating your custom_layout for listview inside getView method ,within adapter.
Simply pass the context and values needed to be populated in Listview.
new ArrayAdapter<String>(this,items);
Change your adapter constructor to the same.
if it doesn't work please post the adapter code.
Update your code like this.
public class CustomListAdapter extends ArrayAdapter<String> {
private Context mContext;
private int id;
private List<String> items ;
private LayoutInflater inflater;
public CustomListAdapter(Context context,List<String> list )
{ super(context,list);
this.mContext = context;
this.items = list ;
this.inflater=LayoutInflater.from(context)
}
public int getCount()
{
items.length;
(or)
items.size();
}
#Override
public View getView(int position, View v, ViewGroup parent)
{
if(v== null){
v = this.inflater.inflate(R.layout.custom_layout_rachel, null);
}
TextView text = (TextView) v.findViewById(R.id.textView);
if(items.get(position) != null )
{
text.setTextColor(Color.WHITE);
text.setText(items.get(position));
text.setBackgroundColor(Color.RED);
int color = Color.argb( 200, 255, 64, 64 );
text.setBackgroundColor( color );
}
return v;
}
changes in your code
lvItems = (ListView) findViewById(R.id.lvItems);
items = new ArrayList<String>();
readItems();
itemsAdapter = new CustomListAdapter<String>(this, items);
lvItems.setAdapter(itemsAdapter);
Related
I am creating a playlist with 2 lines of name and genre, how to I can delete it.
This is MainActivity :
String[] gene, sl;
...
adp = new Adapter(MainActivity.this, gene, sl);
lv.setAdapter(adp);
This is Adapter
public class Adapter extends ArrayAdapter<String> {
private final Activity context;
private final String[] gene;
private final String[] sl;
SharedPreferences preferences;
public Adapter(Activity context, String[] gene ,String[] sl) {
super(context, R.layout.activity_m , gene);
this.context = context;
this.gene = gene;
this.sl = sl;
}
private class ViewHolder{
TextView txtgene, txtsl;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = context.getLayoutInflater();
view = inflater.inflate(R.layout.activity_m, null, true);
holder = new ViewHolder();
holder.txtgene = (TextView) view.findViewById(R.id.txtgene);
holder.txtsl = (TextView) view.findViewById(R.id.txtsl);
view.setTag(holder);
}else{
holder = (ViewHolder) view.getTag();
}
if (gene[position] != null) {
holder.txtgene.setText(gene[position]);
}
holder.txtsl.setText(sl[position]);
return view;
}
}
How to remove an item when you know its exact position ?
Thank !
You are using the ArrayAdapter constructor that takes an array. This in turn will create an immutable List internal to the ArrayAdapter. So, you will not be able to modify your adapter going this route.
Instead, make a new ArrayList from your array and call the ArrayAdapter constructor that takes a List.
So, change the super call in your Adapter constructor to this:
super(context, R.layout.activity_m, new ArrayList<>(Arrays.asList(gene)));
And then, when you want to remove an item given it's position, do this:
adp.remove(getItem(position));
PS: You should consider refactoring your gene and sl arrays into a class and then use it as the type of your List.
I am trying to create my first Custom Adapter to generate a listview for my android app. I am getting my data from an Api call and then process it and store it in an arraylist:-
class Person{
String bioguide;
String image;
String lastname;
String firstname;
String district;
String state;
String party;}
public static ArrayList<Person> personData = new ArrayList<Person>();
Now in the onpostexecute section I am trying to create a listview and custom adapter to display my data as follows:-
ListView yourListView = (ListView) rootView.findViewById(R.id.state_listView);
ListAdapter customAdapter = new ArrayAdapter<Person>(ByState.this, R.layout.bystate_itemview,personData);
yourListView .setAdapter(customAdapter);
}
}
public class ListAdapter extends ArrayAdapter<Person> {
public ListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public ListAdapter(Context context, int resource, ArrayList<Person> items) {
super(context, resource, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.bystate_itemview, null);
}
Person p = getItem(position);
if (p != null) {
TextView tt1 = (TextView) v.findViewById(R.id.last_name);
TextView tt2 = (TextView) v.findViewById(R.id.first_name);
if (tt1 != null) {
tt1.setText(p.getLastname());
}
if (tt2 != null) {
tt2.setText(p.getFirstname());
}
}
return v;
}
}
}
I got the above code following some internet tutorial. The thing is I am getting an error in the line where I use the customadapter first to invoke the constructor of custom adapter. It says cannot resolve constructor. Can someone help me in understanding this. I know I have not defined the proper constructor for my case please let me know the changes. I am creating the listview inside a fragment and the fragment class name is ByState.
In second line replace
ListAdapter customAdapter = new ArrayAdapter<Person>(ByState.this, R.layout.bystate_itemview,personData);
by
ListAdapter customAdapter = new ListAdapter(ByState.this, R.layout.bystate_itemview, personData);
You create your own adapter class, but invoke standart ArrayAdapter
Here's the code with the problem:
//declarations:
private ArrayAdapter<String> listAdapter;
private ArrayAdapter<String> listAdapter2;
String [] nomi=null;
String[] famiglia=null;
private ListView mainListView;
// other code bla bla bla...
mainListView = (ListView) findViewById(R.id.listView);
// other code bla bla bla...
nomi = new String[res.size()];
for (int i = 0; i < res.size(); i++) {
nomi[i] = res.get(i).getNomignolo();
}
famiglia= new String[res.size()];
for(int i=0; i<res.size();i++){
famiglia[i] = res.get(i).getFamiglia();
}
ArrayList<String> listaNomi = new ArrayList<String>();
listaNomi.addAll(Arrays.asList(nomi));
ArrayList<String> listaFamiglie = new ArrayList<String>();
listaFamiglie.addAll(Arrays.asList(famiglia));
listAdapter = new ArrayAdapter<String>(HomeActivity.this, R.layout.row, R.id.button3, listaNomi);
listAdapter2 = new ArrayAdapter<String>(HomeActivity.this, R.layout.row, R.id.button6, listaFamiglie);
mainListView.setAdapter(listAdapter);
mainListView.setAdapter(listAdapter2);
It works, but only in part, because when i start the app i can find only the result of the second setAdapter method. How can i achieve also the result of all the setAdapter methods? Thanks.
try to add objects of second list in first on
nomi = new String[res.size()];
for (int i = 0; i < res.size(); i++) {
nomi[i] = res.get(i).getNomignolo() + " " +res.get(i).getFamiglia();
}
//list of object with name and family
create adapter
listAdapter = new ArrayAdapter<String>(HomeActivity.this, R.layout.row, R.id.button3, listaNomi);
mainListView.setAdapter(listAdapter);
you cannot set multiple adapter for one listview.
How to create custom array adapter:
public class CustomAdapter extends ArrayAdapter<Person>{
private final Activity context;
private ArrayList<Person> Items;
public CustomAdapter (Activity context, int layout,ArrayList<Person> persons) {
super(context, layout, carriers);
// TODO Auto-generated constructor stub
this.context = context;
this.Items = persons;
}
static class ViewHolder {
public Button name;
public Button family;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
// Recycle existing view if passed as parameter
// This will save memory and time on Android
// This only works if the base layout for all classes are the same
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.item, null, true);
holder = new ViewHolder();
holder.name= (TextView) rowView.findViewById(R.id.name);
holder.family= (TextView) rowView.findViewById(R.id.family);
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
holder.name.setText(Items.get(position).getName());
holder.family.setText(Items.get(position).getFamily());
return rowView;
}
}
and create PErson Object:
public class PErson{ public String name; public String family;
public Person();
public String getName(){ return name;}
public String getFamily(){return family;}
}
and this is item xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="wkjdhk"
android:textColor="#color/green"
android:textSize="12sp" />
<Button
android:id="#+id/family"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="wkjdhk"
android:textColor="#color/green"
android:textSize="12sp" />
</RelativeLayout>
this is how to call from activity:
adapter = new MyCustomAdapter(CarrierSummaryActivity.this,nomi,R.layout.item);
mainListView.setAdapter(adapter);
Can you please do like this way ?
First List:
ArrayList<String> a = new ArrayList<String>();
a.add("a");
a.add("b");
a.add("c");
Second List:
ArrayList<String> b = new ArrayList<String>();
b.add("d");
b.add("e");
b.add("f");
Add a to b:
b.addAll(a);
Merge both list:
ArrayList<String> union = new ArrayList<String>(a);
union.addAll(b);
Set Adapter on ListView:
listAdapter = new ArrayAdapter<String>(HomeActivity.this, R.layout.row, R.id.button3, union);
mainListView.setAdapter(listAdapter);
Hope this will help you.
This is not possible, whenever you are setting second adapter to listview, your first adapters data get replaced with second.
LISTVIEW CAN DISPLAY SINGLE ADAPTER DATA AT SINGLE TIME.
If you want to display data from multiple sources to ListView then first merge all all data and then use single adapter. Do something like below
dataList1 (From source A)
datalist2 (From source B)
datalist3 = dataList1 + dataList2;
setDapter(dataList3)
You should implement your custom adapter so it can draw the list just like you want.
class MyAdapter extends BaseAdapter
{
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Here you can return a View with any data in any way
}
}
Hope this helps.
How do I program my adapter in order to visualize the contents of an ArrayList in a onPostExecute inside an AsynkTask?
I have got the following class:
class PlatoCuenta{
public String id;
public String name;
public Integer served_as;
public String served;
public String price;
public String quantity;
public String title_cuenta;
}
I have got the following array list:
ArrayList<PlatoCuenta> bebidas=new ArrayList<PlatoCuenta>();
bebidas=new ArrayList<PlatoCuenta>();
JSONArray mArray = new JSONArray(jsonstr);
for(int i = 0; i < mArray.length(); ++i) {
JSONObject currentObject = mArray.getJSONObject(i);
PlatoCuenta producto= new PlatoCuenta();
SectionItem SectionCuenta = new SectionItem();
producto.id=currentObject.getString("id");
producto.served=currentObject.getString("served");
if(currentObject.getString("price").equals("None"))
producto.price="0.00";
else
producto.price=currentObject.getString("price");
producto.name= currentObject.getString("product_name");
producto.quantity=currentObject.getString("product_number");
producto.served_as = currentObject.getInt("serv_order");
if(producto.served_as==0){
SectionCuenta.title="bebidas";
producto.title_cuenta=SectionCuenta.title;
bebidas.add(producto);
}
if(producto.served_as==2){
SectionCuenta.title="entrantes";
producto.title_cuenta=SectionCuenta.title;
bebidas.add(producto);
}
}
Assume that you have ArrayList<PlatoCuenta> bebidas=new ArrayList<PlatoCuenta>();. The general steps for visualize a listview are:
Create a row layout row.xml
Create an adapter for the row
Set adapter to the listview.
Again, suppose that you already have the design of your row.xml. To create an adapter (step 2).
public class MyAdapter extends BaseAdapter {
public MySimpleArrayAdapter(Context context, ArrayList list) {
super(context, R.layout.rowlayout, values);
//....
}
#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.xml, parent, false);
//continue creating your row here
return rowView;
}
}
And in onPostExecute:
MyAdapter adapter = new MyAdapter(context,bebidas);
listView.setAdapter(adapter);
Good tutorial: Custom ListView
I am trying to create an onDisimiss listener to my app as for now this is what i have
The activity
public class listview_test extends Activity {
ListView list;
String[] web = {
"Google Plus",
"Twitter",
"Windows",
} ;
Integer[] imageId = {
R.drawable.ic_launcher,
R.drawable.icon,
R.drawable.ic_launcher,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_test);
final CustomList adapter = new
CustomList(listview_test.this, web, imageId);
list=(ListView)findViewById(R.id.list);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(listview_test.this, "You Clicked at " +web[+ position], Toast.LENGTH_SHORT).show();
}
});
SwipeDismissListViewTouchListener touchListener =
new SwipeDismissListViewTouchListener(
list,
new SwipeDismissListViewTouchListener.DismissCallbacks() {
#Override
public boolean canDismiss(int position) {
return true;
}
#Override
public void onDismiss(ListView listView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
adapter.remove(adapter.getItem(position));
}
adapter.notifyDataSetChanged();
}
}
);
list.setOnTouchListener(touchListener);
// Setting this scroll listener is required to ensure that during ListView scrolling,
// we don't look for swipes.
list.setOnScrollListener(touchListener.makeScrollListener());
}
}
And the custom adapter
public class CustomList extends ArrayAdapter<String>{
private final Activity context;
private final String[] web;
private final Integer[] imageId;
public CustomList(Activity context,
String[] web, Integer[] imageId) {
super(context, R.layout.weather_item, web);
this.context = context;
this.web = web;
this.imageId = imageId;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.weather_item, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.city);
ImageView imageView = (ImageView) rowView.findViewById(R.id.info_image);
txtTitle.setText(web[position]);
imageView.setImageResource(imageId[position]);
return rowView;
}
For some reason every time i am swiping an item to dismiss it force closes and gives me this exception
java.lang.UnsupportedOperationException
In this line
adapter.remove(adapter.getItem(position));
java.lang.UnsupportedOperationException
is thrown when you back an Adapter by an array or non-modifiable List. Since you cannot change their size, deleting is impossible.
Instead, modify your Adapter so it accepts a List instead of an array and make sure that the List you pass off is fully flexible.
Something like
List <String> web = new ArrayList <String> ();
web.add ("Google Plus");
web.add ("Twitter");
//etc.
is enough to ensure a flexible list.
This means that your CustomList adapter should also call up to the superclass constructor that also accepts in a List, which in this case is
public ArrayAdapter (Context context, int resource, List<T> objects)
For more information refer to the ArrayAdapter documentation.