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
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've set up a grid of ImageViews with TextView overlays. My ImageAdapter code is as follows:
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
View grid;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
grid = new View(mContext);
grid = inflater.inflate(R.layout.image, null);
TextView textView = (TextView)grid.findViewById(R.id.mastery_text);
imageView = (ImageView)grid.findViewById(R.id.mastery_image);
grid.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
grid.setPadding(8, 8, 8, 8);
grid.setBackgroundResource(R.color.orange);
imageView.setImageResource(mThumbIds[position]);
} else {
grid = (View) convertView;
}
return grid;
}
The corresponding XML layout for my ImageAdapter is this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_practitioner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/mastery_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom"
android:background="#bbffffff"
android:focusable="false"
android:focusableInTouchMode="false" >
<TextView android:id="#+id/mastery_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:textColor="#color/black"
android:gravity="bottom|center"
android:textSize="12sp"
android:textAllCaps="true"
android:paddingBottom="0dp"
android:text="3/3"
/>
</LinearLayout>
</FrameLayout>
XML code for my GridView (activity class):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="4"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</LinearLayout>
Here is the onCreate method of my main activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_masteries);
GridView gridview = (GridView) findViewById(R.id.gridview);
ImageAdapter adapter = new ImageAdapter(this);
gridview.setAdapter(adapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(Masteries.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
}
I want to, after initializing the grid with the images, change one of the ImageViews from my activity class, given its position on the grid. How would I do that?
I'm not asking to change the image in response to an onItemClick.
Thanks in advance!
Edit:
I'm thinking of creating a changeImage(int position, int imageId) method in my Adapter and calling that from my activity class. Is that the right approach?
In your adapter:
public void updateImage(int position, int resourceId)
{
mThumbIds[position] = resourceId;
notifyDataSetChanged();
}
In your activity:
mAdapter.updateImage(<position>, <image_resource_id>);
Notes
You will have to make the adapter a member of your activity
The main idea is that you modify the backing data and and notify the GridView that this has changed and it is time to be redrawn
Your getView() method implementation needs a lot of improvement. It will cause lots of bugs once the system starts recycling the views (the convertView parameter comes in != null for a position different than it was used for last time)
Here's a sketch of how your getView() should look like:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.image, parent, false);
// next three lines would not be necessary if:
// a) it is the same for every item;
// b) you inflate properly (using the parent);
// c) you specify this in the item's xml (R.layout.image)
convertView.setLayoutParams(new GridView.LayoutParams(150, 150));
convertView.setPadding(8, 8, 8, 8);
convertView.setBackgroundResource(android.R.color.holo_red_light);
viewHolder = new ViewHolder();
viewHolder.mTextView = (TextView)convertView.findViewById(R.id.mastery_text);
viewHolder.mImageView = (ImageView)convertView.findViewById(R.id.mastery_image);
// this could also be set in xml perhaps
viewHolder.mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
// update the values every time we are being asked to update the item,
// because the item might have been reused from a different position
viewHolder.mImageView.setImageResource(mThumbIds[position]);
//viewHolder.mTextView.setText("myText");
return convertView;
}
public static class ViewHolder
{
TextView mTextView;
ImageView mImageView;
}
You can set a unique id to each ImageView using names (See here) or even integer numbers with a sequence or something (increasing at each image you put in the view).
Another good way to do this is using the tags, with setTag() and getTag().
This question has a good answer: What is the main purpose of setTag() getTag() methods of View?
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);
}
...
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*;
}