I'd like to customize some settings (color, margin) for some items on a listview in a listactivity after or before setting the adapter. How can I do that? Is there any function that can I override?
Thank you.
you can use an own listadapter.. http://www.vogella.com/articles/AndroidListView/article.html
This is how you can do to customize item of your list:
Layout of your list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Layout of each item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
</LinearLayout>
And finaly your activity:
public class MyActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_activitty);
final List<String> list = new ArrayList<String>();
list.add("test");
list.add("test");
list.add("test");
final CustomAdapter adapter = new CustomAdapter(this, list);
final ListView listView = getListView();
listView.setAdapter(adapter);
}
public class CustomAdapter extends BaseAdapter {
private Context mContext;
private List<String> mList;
public CustomAdapter(Context context, List<String> list) {
mContext = context;
mList = list;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public String getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Holder holder;
if (convertView == null) {
// if it is the first time you create the row
// you get the layout of each row here
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, null);
// you keep your layout in a holder
holder = new Holder();
holder.mText = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
// if the row has already been created, you get it from the holder
holder = (Holder) convertView.getTag();
}
// you do what you want with the content
holder.mText.setText(getItem(position));
holder.mText.setTextColor(Color.BLUE);
return convertView;
}
private class Holder {
public TextView mText;
}
}
}
Related
I have an ListView with BaseAdapter now I just make some listener to item when I click on item I show some hidden view in item.
Every time I click on some item, I show the hidden view or hide them if views are visible. But the problem I face is that I want to hide the other visible item when the I show a new item.
Here I click on some item and its shows the message date and detail:
Now when I click on other items, I want to hide the first one and show the second, like this:
But here in my code when I click on other item its of course will not hide the previous view. How can I do this trick ?
Simply keep a reference to the last view that was clicked, let's call it mLastViewShown;
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mLastViewShown != null)
hideDetails();
mLastViewShown = view;
showDetails();
}
};
Now you have a variable to hide the details from the last user click.
So you want to hide all item's additional field when you click on some other item. In addition to this you also want to toggle visibility of an item's additional view on click on same item.
Here is your main activity:
public class MainActivity extends AppCompatActivity {
private List<ListData> list=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get the toolbar instance
handleListClick();
list.add(new ListData("George","Surgeon"));
list.add(new ListData("Nancy","Dentist"));
list.add(new ListData("Henry","Nurse"));
}
private void handleListClick() {
ListView listView=findViewById(R.id.listView);
final CustomBaseAdapter customBaseAdapter=new CustomBaseAdapter(this,list);
listView.setAdapter(customBaseAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
customBaseAdapter.setCurrentSelected(position);
customBaseAdapter.notifyDataSetChanged();
}
});
}
}
Here is your custom base adapter:
public class CustomBaseAdapter extends BaseAdapter {
private List<ListData> myList = new ArrayList<ListData>();
private LayoutInflater inflater;
private Context context;
private int previousSelected=-1;
public CustomBaseAdapter(Context context, List<ListData> myList) {
this.myList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context);
}
public void setCurrentSelected(int currentSelected){
if(previousSelected==currentSelected)
previousSelected=-1;
else
previousSelected=currentSelected;
}
#Override
public int getCount() {
return myList.size();
}
#Override
public ListData getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.row_item, parent, false);
mViewHolder = new MyViewHolder(convertView);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
ListData currentListData = getItem(position);
mViewHolder.tvMain.setText(currentListData.getMainText());
if(previousSelected==position){
mViewHolder.tvAdditional.setVisibility(TextView.VISIBLE);
mViewHolder.tvAdditional.setText(currentListData.getAdditionalText());
}else{
mViewHolder.tvAdditional.setVisibility(TextView.GONE);
}
return convertView;
}
private class MyViewHolder {
TextView tvMain, tvAdditional;
public MyViewHolder(View item) {
tvMain = (TextView) item.findViewById(R.id.main_text);
tvAdditional = (TextView) item.findViewById(R.id.additional_text);
}
}
}
Here is your ListData:
public class ListData {
private String mainText;
private String additionalText;
public ListData(String mainText, String additionalText) {
this.mainText = mainText;
this.additionalText = additionalText;
}
public String getMainText() {
return mainText;
}
public void setMainText(String mainText) {
this.mainText = mainText;
}
public String getAdditionalText() {
return additionalText;
}
public void setAdditionalText(String additionalText) {
this.additionalText = additionalText;
}
}
Here is your row_item.xml layout file:
<?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/main_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/additional_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
</LinearLayout>
Here is activity_main.xml layout file:
<?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="match_parent"
android:orientation="vertical"
tools:context="com.dexter.stackoverflow.MainActivity">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
I would like to create a simple populated GridView using BaseAdapter but I keep getting empty list - application runs but there are no Views displayed.
Below are all files are use for this task:
Main:
String[] items = {"Some", "items", "to", "display"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView grid = (GridView)findViewById(R.id.grid);
final TextView text = (TextView)findViewById(R.id.text);
MyAdapter adapter = new MyAdapter(getApplicationContext(), items);
grid.setAdapter(adapter);
MyAdapter:
LayoutInflater inflater;
Context context;
String[] myData;
public MyAdapter(Context context, String[] myData) {
this.context = context;
this.myData = myData;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return myData[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.grid, parent, false);
TextView text = (TextView) convertView.findViewById(R.id.textView);
text.setText(myData[position]);
return convertView;
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.random.MainActivity">
<GridView
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="40dip"
android:horizontalSpacing="5dip"
android:numColumns="auto_fit"
android:columnWidth="100dip"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</android.support.constraint.ConstraintLayout>
grid.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">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
/>
</LinearLayout>
I have checked in various sources countles times and I did not manage to find an error in my code. It would be amazing if someone would take a look at it and find a reason for empty activity as the reason is probably obvious.
Your getCount method always return 0. Return the number of elements in your myData array instead.
#Override
public int getCount() {
return myData.length;
}
You can try this my friend
public class MyAdapter extends BaseAdapter {
Context context;
String[] data;
public MyAdapter(Context context, String[] myData) {
this.context = context;
this.data = myData;
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int position) {
return data[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.grid, null);
}
TextView text = (TextView) convertView.findViewById(R.id.textView);
text.setText(data[position]);
return convertView;
}
}
I am using Custom Adapter for ListView. Each ListView item contains ImageButton which will delete that Item. Now, I want to refresh full ListView when anyone click on ImageButton. How to do this ?
Or is there anyway to check ImageButton click on ListView onItemClickListener ? I have already tried notifyDataSetChanged in Custom Adapter but I can't find any changes.
Custom 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="fill_parent"
android:background="#color/lightish"
android:orientation="vertical"
android:padding="10dp" >
<ImageButton
android:id="#+id/imgDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginBottom="-20dp"
android:background="#android:color/transparent"
android:contentDescription="#string/app_name"
android:src="#drawable/ic_delete" />
<TextView
android:id="#+id/tvName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textSize="20sp" />
</LinearLayout>
Custom Adapter java :
public class MyAddressesAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
View vi;
HashMap<String, String> address;
public MyAddressesAdapter(Activity a,
ArrayList<HashMap<String, String>> arlData) {
activity = a;
data = arlData;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, final View convertView, ViewGroup parent) {
vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.my_address_view, parent, false);
final TextView tvName = (TextView) vi.findViewById(R.id.tvName);
address = new HashMap<String, String>();
address = data.get(position);
tvName.setText(address.get("PersonName"));
return vi;
}
In main activity java :
myAddressesAdapter = new MyAddressesAdapter(
getActivity(), addressList);
lvMyAddresses.setAdapter(myAddressesAdapter);
put code in getview method in adapter
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//your code here
data.remove(position);
notifyDataSetChanged();
}
});
I am currently working on a very basic android application and have encountered an obstacle I cannot solve on my own.
In my application I want to have a start screen with a ListView. In each Line of this ListView there should be a Button and a TextView. I want to have approximately 5 Lines. When you click on each of the Button you should be able to get to different Activities. How do I do that? I read something about adapters but I am still not sure how to build this.
Here's my xml code for the TextView and the Button:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:id="#+id/rl01">
<TextView
android:layout_width= "wrap_content"
android:layout_height="50dp"
android:id="#+id/text01"
android:text="hello"
android:textSize="24dp"
android:textColor="#color/abc_search_url_text_normal"
android:paddingRight="#dimen/activity_horizontal_margin"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_toRightOf="#id/text01"
android:text="Press Me!"
/>
</RelativeLayout>
The xml layout you have posted, will be used as each listview item.
Step 1:
Create a class which extends BaseAdapter;
public class CustomAdapter extends BaseAdapter
{
Context con;
String[] data;
public CustomAdapter (Context context, String[] data)
{
this.con = context;
this.data = data;
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int position) {
return data[position];
}
#Override
public long getItemId(int position) {
return 0;
}
//this method will be called for every item of your listview
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView= inflater.inflate(R.layout.customview, parent, false);
TextView text = (TextView) view.findViewById(your text view id); //recognize your view like this
text.setText(data[position]);
return convertView;
}
}
Step 2:
In your activity, recognize your listview:
yourListViewReference = (ListView) findViewById(R.id.your_list_view_id);
And initialize String array:
String[] data = {"item 1", "item2", "item3"}; //how many items you want
And then create instance of custom adapter you created, and set it to listview:
CustomAdapter ad = new CustomAdapter(this, data);
yourListViewReference.setAdapter(ad);
And sorry for my bad english. I am actually working on it.
This article from Vogella is really useful for what you want to do.
Basically, you'll create an Adapter that extends the BaseAdapter class as follows:
public class Adapter extends BaseAdapter {
private List<Item> mItems;
private Context mContext;
public EventAdapter(Context context, List<Event> items) {
mContext = context;
mItems = items;
}
public View getView(int position, View convertView, ViewGroup parent) {
// This recycles your view and prevents constant inflation, which can really hit your performance.
View rowView = convertView;
if (rowView == null) {
ViewHolder viewHolder = new ViewHolder();
rowView = inflater.inflate(R.layout.yourLayout, parent, false);
viewHolder.text = (TextView) rowView.findViewById(R.id.yourTextViewId);
viewHolder.button = (Button) rowView.findViewById(R.id.yourButtonId);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
// Get the correct item by position
Item item = item.get(position);
// Update the row layout with your item data
holder.text.setText(item.text);
holder.button.setButton(item.button);
// Return your row view
return rowView;
}
#Override
public int getCount() {
return mItems.size();
}
#Override
public Object getItem(int position) {
}
#Override
public long getItemId(int position) {
}
static class ViewHolder {
public TextView text;
public Button button;
}
Afterwards you just need to set this adapter to your ListView or RecyclerView by doing
listView.setAdapter(new Adapter(this, items));
I would write a simple example:
You dont need a button in listview row, just implement onItemClick();
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="#+id/custom_list"
android:longClickable="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
list_row.xml
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:id="#+id/rl01">
<TextView
android:layout_width= "wrap_content"
android:layout_height="50dp"
android:id="#+id/text01"
android:text="hello"
android:textSize="24dp"
android:textColor="#color/abc_search_url_text_normal"
android:paddingRight="#dimen/activity_horizontal_margin"
/>
MainActivity.java
oncreate()
{
....
lv1 = (ListView) result.findViewById(R.id.custom_list);
String[] listdata = {"txt1", "txt2", "txt3", "txt4", "txt5"};
ListAdapter listAdapt = new ListAdapter(this, listdata );
lv1.setAdapter(listAdapt);
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//do ur work here when list row selected
}
});
..
}
ListAdapter.java
public class ListAdapter extends BaseAdapter {
String[] listData;
private LayoutInflater layoutInflater;
public CustomListAdapter(Context aContext, String[] listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(aContext);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row, null);
TextView tv1 = (TextView)convertView.findViewById(R.id.text01);
tv1.setText(listData.[position]);
return convertView;
}
I have an android activity with a gridview, each cell contains a textview with a single character (so there are around 60-70 characters/cells on the screen at a time). The scrolling of the gridview is unacceptably slow and unsmooth. I tried replacing the gridview with a listview, and the scrolling of the listview is much faster. How can i speed this up?
The activity layout is:
<?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="match_parent"
android:orientation="vertical" >
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="56dp"
android:numColumns="auto_fit" >
</GridView>
</LinearLayout>
And inside each cell is this layout:
<?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="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="40sp" />
</LinearLayout>
And the code for the activity is:
public class TestGridActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_activity);
GridView gridView = (GridView) findViewById(R.id.gridView1);
ArrayList<Map<String, String>> list = getData();
SimpleAdapter arrayAdapter = new SimpleAdapter(this, list,
R.layout.grid_layout, new String[] { "literal"},
new int[] { R.id.textView1});
gridView.setAdapter(arrayAdapter);
}
}
edit: pks asking to post adapter code, the above code I have used a generic simpleAdapter, but i have tried a custom view, which didn't help.
public class GridAdapter extends BaseAdapter {
private Context context;
private ArrayList<Map<String, String>> list;
private LayoutInflater inflater;
public static class ViewHolder {
TextView textView1;
int position;
}
public GridAdapter(Context c, ArrayList<Map<String, String>> l) {
context = c;
list = l;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return list.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = inflater.inflate(R.layout.grid_layout, null);
holder = new ViewHolder();
holder.textView1 = (TextView) convertView.findViewById(R.id.textView1);
holder.position = position;
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView1.setText(list.get(position).get("character"));
return convertView;
}
}
I've also tried creating all the views in advance, and that didn't help scrolling speed.