This question has been asked here a link
Also I want to clarify the question
I have 10 List Items in a Listview
I want to have the deviderheight of each List Items differently like for first Item it should be setDividerheight(2) for 2nd setDividerheight(4) like this..
I have made a custom Adapeter in which I am setting my Layout Like
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if(position ==2)
{
if (v != convertView && v != null) {
ViewHolder holder = new ViewHolder();
// TextView tv = (TextView) v.findViewById(R.id.artist_albums_textview);
// holder.albumsView = tv;
convertView = mInflater.inflate(R.layout.jazz_artist_list_item, null);
holder.albumsView = (TextView)convertView.findViewById(R.id.artist_albums_textview);
// lv.setDividerHeight(8);
v.setTag(holder);
}
}
else
{
if (v != convertView && v != null) {
ViewHolder holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.jazz_artist_list_item, null);
holder.albumsView = (TextView)convertView.findViewById(R.id.artist_albums_textview);
// lv.setDividerHeight(2);
v.setTag(holder);
}
}
}
but this seems not working properly.
Any idea on above this as how to set the divider height of Listview dynamically
Regards,
Laxmikant
//set Divider as you like
listView.setDivider((Drawable) getResources().getDrawable(R.drawable.orange));
//then set the height dynamically
listView.setDividerHeight(1);
in your Activity which has the ListView. Not the Adapter class.
If you what exactly what you wrote in the question. Do this:
let each listView Item layout contain a TextView and a View(divider after each item), then depending on the position parameter you get in the getView() method change the Height of the View.
ListView Item layout:
<?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:padding="5dp" >
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/logo"
android:padding="5dp"
android:textSize="14dp" >
</TextView>
<View
android:id="#+id/view"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_below="#id/label"
android:background="#drawable/orange" />
</RelativeLayout>
now in the adapter class your ViewHolder contains the TextView and also the View.
so,
Holder.View = (View)convertView.findViewById(R.id.view);
if(position == 0){
(Holder.View).setHeight(2);
}
and so on.
A slight tweak to above got it working for me (no setHeight() method in View?), thanks:
Holder.View = (View)convertView.findViewById(R.id.view);
if(position == 0){
(Holder.View).getLayoutParams().height = *your desired height e.g. 20*;
}
Related
I am using an custom adapter and I have the problem with getView method. Here is my code -
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi = convertView;
if (vi == null)
vi = inflater.inflate(R.layout.list_item, null);
if(position==0){
TextView text1 = (TextView) vi.findViewById(R.id.text1);
text1.setText(data[position]);
}else if(position==1){
TextView text2 = (TextView) vi.findViewById(R.id.text2);
text2.setText(data[position]);
}
return vi;
}
and here is the XML 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:background="#android:color/black"
android:textColor="#android:color/white"
android:id="#+id/text1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:background="#android:color/green"
android:textColor="#android:color/white"
android:id="#+id/text2" />
</LinearLayout>
Actually my if command is working but the other blank textView also appears with it.
Suppose If position==0 then "#+id/text1" should be displayed, but "#+id/text2" also get displayed with no text.
I want only one textview to be displayed, not the other one. How to do that?
position is the index of the currently displayed item in the adapter, not which TextView is being displayed.
Each row of your Adapter has two TextViews, and I assume you have some string that needs to be displayed in both views.
As an example, try this instead.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String item = String.valueOf(data[position]);
View v = convertView;
if (v == null) {
v = inflater.inflate(R.layout.list_item, null);
}
TextView text1 = (TextView) v.findViewById(R.id.text1);
TextView text2 = (TextView) v.findViewById(R.id.text2);
text1.setText("1: " + item);
text2.setText("2: " + item);
return v;
}
I want only one textview to be displayed, not the other one. How to do that?
Then it sounds like you don't want two TextViews in one layout...
If you question is literally "How to display more than one TextView in a ListView", then you should put more than one value into that data array.
I want to implement grid, which will be populated dynamically. I want to know what is the best approach to implement this Relative layout(List View) or Grid Layout?
You can generate a GridView dynamically.
GridView would contain of ImageView and TextView as per your need. You will have to use your custom adapter. In it's getView method, populate the ImageView and TextView.
Example:
GridView item.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imgItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/txtItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="trebuchet"
android:textColor="#android:color/black"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
Java code:
A POJO class for item:
public class Item
{
String title;
Drawable image;
//getter setter
}
Adapter class:
//getView method in your adapter class
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View itemView = convertView;
ViewHolder holder = null;
if (itemView == null)
{
final LayoutInflater layoutInflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
itemView = layoutInflater.inflate(resourceId, parent, false);
holder = new ViewHolder();
holder.imgItem = (ImageView) itemView.findViewById(R.id.imgItem);
holder.txtItem = (TextView) itemView.findViewById(R.id.txtItem);
itemView.setTag(holder);
}
else
{
holder = (ViewHolder) itemView.getTag();
}
Item item = getItem(position);
holder.imgItem.setImageDrawable(item.getImage());
holder.txtItem.setText(item.getTitle());
return itemView;
}
Now add adapter data in your Activity class and then set that adapter to GridView.
Refer to this and this
Hope it helps.
Simply use GridView with a custom adapter. Each time you want the view to update, call notifyDataSetChanged() on the adapter.
You want GridView. Easy example here. In your case, you will need to make an XML layout for each row to accommodate both your TextView and ImageView. Other answers here address that.
In a fragment, I have a ListView that has a custom ParseQueryAdapter<T>. The problem may not have anything to do with Parse, although I'm not sure.
As I was testing my app, I noticed something very strange. When I would scroll down my ListView, all the visible ListView items would be drawn on top of the next ListView item as seen in the second image below.
The list initialized properly as such:
As you can see, in my list item layout, I have an ImageView (ParseImageView to be specific) and a TextView. The TextView now displays some notes (don't mind the ID user_name_text_view) and the ImageView displays a placeholder blank profile picture.
When I scrolled down, the list looked like:
Here's my list view layout named fragment_post_view_list_view:
<?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" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Here's my list item layout named list_item_post_view:
<?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">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
android:background="#drawable/com_facebook_profile_picture_blank_square" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Here's my adapter named PostViewListViewAdapter:
public class PostViewListViewAdapter extends ParseQueryAdapter<Post> {
// call superclass with a query to populate list view
public PostViewListViewAdapter(Context context, final String[] postsObjectIds) {
super(context, new ParseQueryAdapter.QueryFactory<Post>(){
public ParseQuery<Post> create() {
ParseQuery<Post> query = Post.getQuery();
query.whereContainedIn("objectId", Arrays.asList(postsObjectIds));
return query;
}
});
}
// this is similar to getView method in an adapter
#Override
public View getItemView(Post post, View v, ViewGroup parent) {
if(v == null) {
v = View.inflate(getContext(), R.layout.list_item_post_view, null);
}
super.getItemView(post, v, parent);
TextView usernameTextView = (TextView) v.findViewById(R.id.user_name_text_view);
usernameTextView.setText(post.getNotes()); // some string
return v;
}
}
How can I fix this problem?
Is this an issue with XML or Java?
I was following the two tutorials from Parse and the example from the Parse docs:
MealSpotting
Parse Query Adapter
I set the adapter and ListView here:
View rootView = inflater.inflate(R.layout.fragment_post_view_list_view, container, false);
mPostsObjectIds = SOME_STRING[];
PostViewListViewAdapter adapter = new PostViewListViewAdapter(getActivity(), mPostsObjectIds);
ListView listView = (ListView) rootView.findViewById(R.id.post_list_view);
listView.setAdapter(adapter);
I've tried getting rid of the ParseImageView in my list item layout, but my TextViews still draw on top of each other when I scroll.
Edit:
I forgot to mention that the list items display on top of each other after an orientation change.
I tested this on my Galaxy S5 (Android version 4.4.2 and Parse 1.4.1).
In my Activity, I show the Fragment here (called PostViewListViewFragment):
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
Try below layout :
<?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"
android:orientation="vertical" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none" >
</ListView>
</RelativeLayout >
Make Sure your adapter like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.rowlayout, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
String s = names[position];
holder.text.setText(s);
return rowView;
}
}
PS:You should watch this Google IO video about Listview,and here is the slides.
First create a ViewHolder class
static class ViewHolder {
protected TextView usernameTextView;
}
Then change your getItemView method like below
public View getItemView (Post post, View convertView , ViewGroup parent)
{
ViewHolder viewHolder = null;
if (convertView == null)
{
LayoutInflater inflator = context.getLayoutInflater();
convertView = inflator.inflate(R.layout.list_item_post_view, null);
viewHolder = new ViewHolder();
viewHolder.usernameTextView = (TextView)convertView.findViewById(R.id.user_name_text_view);
convertView.setTag(viewHolder);
convertView.setTag(R.id.user_name_text_view, viewHolder.usernameTextView);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.usernameTextView.setText(post.getNotes()); // some string
return convertView;
}
The problem seems to be in your list item layout -
Change it to this -
<?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">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Probably you have extra background for each list item set that is causing such effect.
Alter and watch.
Hope this gives you idea!
Try changing your list view layout height to match_parent.
Credit to #VedPrakash for helping me fix this.
In case it helps anyone, I fixed the problem by replacing the fragment not adding it. So I changed this line from:
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
to:
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new PostViewListViewFragment()).commit();
I want to add dynamic header in a list view, i.e dynamic data for the list view header which will come from the parsed information at the time of loading the list view.
Please read my scenario below. It is must to understand my problem.
Here i am doing it like this using getItemType for the position 0 of the list view.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
int type = getItemViewType(position);
if(type==TYPE_HEADER){
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.my_basket_small_item, parent,false);
convertView.setTag(holder);
}else{
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.my_basket_small_item, parent,false);
holder.tv_price = (TextView)convertView.findViewById(R.id.tv_price);
holder.tv_distance = (TextView)convertView.findViewById(R.id.tv_distance);
holder.img_brandLogo = (ImageView)convertView.findViewById(R.id.img_brandlogo_top);
holder.img_beerCanLogo = (ImageView)convertView.findViewById(R.id.img_beerCan);
holder.click4map = (Button)convertView.findViewById(R.id.btn_click_for_map);
holder.offers = (Button)convertView.findViewById(R.id.btn_my_basket_offers);
}
}
else{
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
My problem is that I want to show the fixed Header with dynamic data plus the list view rows (total number of arraylist size).
Right now it is working for one row less, as one row is occupied by the list view header.
Scenario :
for example 4 list view rows are coming (without header)
When I use header, again 4 rows are coming, I just want that when I use header, 1 header plus 4 rows should come.
Hope you understand.
Thanks
You should add header by calling:
<ListView>.addHeaderView(<HeaderView>,null, false);
And only set items using adapter.
in your current implementation u can override:
#Override
public int getCount() {
// TODO Auto-generated method stub
return <list>.size()+1;
}
There is another approach to this issue - every view item contains header with visibility being managed in getView method.
Your list item layout file may look like this:
<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="vertical" >
<LinearLayout
android:id="#+id/header"
android:visibility="gone"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="headerTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/itemImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/itemTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
and getView() may look like this:
if(converView == null) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.my_basket_small_item, parent, false);
holder = new ViewHolder();
holder.header = convertView.findViewById(R.id.header);
holder.headerTextView = (TextView)convertView.findViewById(R.id.headerTextView);
holder.tv_price = (TextView)convertView.findViewById(R.id.tv_price);
holder.tv_distance = (TextView)convertView.findViewById(R.id.tv_distance);
holder.img_brandLogo = (ImageView)convertView.findViewById(R.id.img_brandlogo_top);
holder.img_beerCanLogo = (ImageView)convertView.findViewById(R.id.img_beerCan);
holder.click4map = (Button)convertView.findViewById(R.id.btn_click_for_map);
holder.offers = (Button)convertView.findViewById(R.id.btn_my_basket_offers);
} else {
holder = (ViewHolder)convertView.getTag();
}
int type = getItemViewType(position);
if(type==TYPE_HEADER){
holder.header.setVisibility(View.SHOW);
holder.headerTextView.setText("Header");
}else{
holder.header.setVisibility(View.GONE);
}
...
I have 3 columns in a gridview and in every cell is a button but the first column should be thinner than the others but I'm not able to accomplish that, here the code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/cell"
android:layout_height="12dp"
android:layout_width="wrap_content"
android:background="#ffffff"
android:textColor="#000000"
/>
</RelativeLayout>
And here the java code:
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.cell, parent, false);
}
gridcell = (Button) row.findViewById(R.id.cell);
String tmp = list.get(position);
gridcell.setTextSize(10);
gridcell.setText(tmp);
//first column
if ((position % 3) == 0) {
gridcell.setBackgroundColor(Color.LTGRAY);
//width should be changed
gridcell.setWidth(5);
} else {
gridcell.setBackgroundColor(Color.BLUE);
gridcell.setWidth(50);
}
return row;
}
Any suggestions
Gridviews with different column widths wont work.
You should use a Listview with a LinearLayout in each Row instead.
See here: GridView with different column sizes