I have a ListView, where i changed appearence of row, but listview have size of one row, instead of fullscreen.
list_item.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="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textView_news_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#0082A8" />
<TextView
android:id="#+id/textView_news_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
tab_news.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/list_news"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
Making Adapter:
public class RSSAdapter extends ArrayAdapter<RSSitem> {
Context context;
int layoutResourceId;
ArrayList<RSSitem> data = null;
SimpleDateFormat sdf = new SimpleDateFormat("kk:mm ");
public RSSAdapter(Context context, int layoutResourceId, ArrayList<RSSitem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
NewsHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new NewsHolder();
holder.txtTime = (TextView)row.findViewById(R.id.textView_news_time);
holder.txtNews = (TextView)row.findViewById(R.id.textView_news_header);
row.setTag(holder);
}
else
{
holder = (NewsHolder)row.getTag();
}
RSSitem item = data.get(position);
holder.txtTime.setText(sdf.format(item.getPubDate()));
holder.txtNews.setText(item.getTitle());
return row;
}
static class NewsHolder
{
TextView txtTime;
TextView txtNews;
}
Items are scrolling.
Sorry for bad English. Thanks for help
Advice of #Varun didn't help
I found mistake. Thanks. Answer in "answers")
I Found mistake.
tab_news was in ScrollView of TabHost.
So stupid mistake(
Thanks for help.
Update:ListView must not be underScrollView in xml. If it is,the same problem occurs.
Update 2 :You may use NestedScrollView
If you use ListView inside ScrollView, you have this issue. And my solution is following as:
1. Create a custom listview which is non scrollable
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
2. Use above custom class for xml file
<xx.xx.NonScrollListView
android:id="#+id/lv_nonscroll_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</xx.xx.NonScrollListView>
It worked well on all OS-version for me.
Hope best for you.
In list_item.xml's parent LinearLayout, you are using android:layout_height="fill_parent" Obviously it is going to expand vertically.
OR:
use monitor tool, go to hierarchy viewer, inspect the running Layout in detail. Find the View with problem, check its attributes/properties are correct, move to its parent View and check it, until you find the issue.
I think Listview is taking only one record from your data. Just check that have you got all the data, which you are keen to show in Listview.
OR
Please check your list_item.xml, Replace
<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="**wrap_content**"
android:orientation="vertical" >
instead of,
<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="**fill_parent**"
android:orientation="vertical" >
Changing the height dynamically gives NPE most of the times... the best solution is to create a custom list view that is non scrollable. You'll find a lot of codes for that.
Related
Hey I am working in android. I want to fit children in whole view of recyclerview android. I have horizontal recylerview. I will show what I want in diagram.
Scenario 1
when I have more item in recyclerview, I want to show children like this in my recycler view.
Expected Output
Scenario 2
when I have three item I want to show like this. It will fill whole view in reyclerview.
Expected Output
Scenario 3
When I have Two item in reyclerview, I need to look like this
Expected Output
The problem I am getting that I have 3 item, the view is not filling fully. Actually I want to stretch whole view to full width like Scenario 2.
Actual output
item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:orientation="vertical">
<LinearLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#drawable/drawable_selector"
android:orientation="vertical">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp" />
<TextView
android:id="#+id/subText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp" />
</LinearLayout>
<RelativeLayout
android:id="#+id/tagContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:visibility="gone">
<TextView
android:id="#+id/tagText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="10dp"
android:paddingEnd="10dp" />
</RelativeLayout>
</FrameLayout>
UPDATE
after #Cheticamp suggestion I did this code
companion object {
fun bindView(parent: ViewGroup): XYZViewHolder {
val view = XyzLayoutBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
val lp = view.container.layoutParams
lp.width = parent.measuredWidth / 3
return OptionsViewHolder(
view
)
}
}
As you can see my last item is cut from the end.
I think in my framelayout i Used marginEnd 10 dp is it causing issue? please refer my layout if you need more. And one more thing I didn't divide framelayout instead I take linear layout as container. I am adding my github link.
You can change the width of the RecyclerView item views in onCreateViewHolder(). The ViewGroup parent is the RecyclerView.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)
val lp = view.layoutParams
// Change the width of the item view here
lp.width = parent.measuredWidth / 3 // width is 1/3 of the width of the RecyclerView
return ItemViewHolder(view)
}
Customize frameLayout class
make a class inherit FrameLayout or another layout you use.
public class SquareFrameLayout extends FrameLayout {
public SquareFrameLayout(#NonNull Context context) {
super(context);
}
public SquareFrameLayout(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public SquareFrameLayout(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SquareFrameLayout(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
onMeasure method is important.
then change root layout item recyclerView to SquareFrameLayout (The class built now)
like this:
<com.example.app.SquareFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_rv_item"
android:orientation="vertical"
android:padding="16dp"
android:layout_margin="4dp"
xmlns:tools="http://schemas.android.com/tools">
//your items
</com.example.app.SquareFrameLayout>
You can use flexbox-layout library provided by Google.
You can adjust the items according to your need.
Download the app and see this demo working for you or not. https://github.com/google/flexbox-layout
I have problem that my list view is not showing and the getView method never invoked
here is my list view inside the onCreate in the MainActivity
l = (ListView) findViewById(R.id.listvv);
CustomAdapter adapter = new CustomAdapter(MainActivity.this, maainimg);
l.setAdapter(adapter);
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/white"
tools:context=".MainActivity">
<ListView
android:id="#+id/listvv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:divider="#b4be"
android:dividerHeight="2dp"></ListView>
<LinearLayout
android:id="#+id/ad_holder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:layout_alignParentBottom="true">
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
ads:adSize="BANNER"
ads:adUnitId="#string/BottomBanner">
</com.google.android.gms.ads.AdView>
</LinearLayout>
</LinearLayout>
and here is my CustomAdapter Class it is inside the MainActivity
public class CustomAdapter extends ArrayAdapter<String> {
int[] img;
Activity activity;
ImageButton imageButton;
public CustomAdapter(Activity act, int [] images) {
super(act, R.layout.custom_row);
this.activity=act;
this.img=images;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d("getView","Called!");
View row = convertView;
if(row==null){
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.custom_row, parent, false);
imageButton = (ImageButton) row.findViewById(R.id.preview);}
imageButton.setImageResource(img[position]);
Log.d("added",position+"");
if (getSelectedcolor() == 0) {
imageButton.setColorFilter(Color.RED);
setSelectedcolor(Color.RED);
} else {
imageButton.setColorFilter(Color.parseColor(colorToHexString(getSelectedcolor())));
}
return row;
}
}
and the custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background">
<ImageButton
android:id="#+id/preview"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:src="#drawable/ic_1_red"
android:scaleType="fitXY"
android:background="#drawable/roundedbutton"
/>
</LinearLayout>
Update
here is my array maainimg its not empty
maainimg = new int[]{R.drawable.ic_1_red,R.drawable.ic_2_red,R.drawable.ic_3_red,R.drawable.ic_4_red,R.drawable.ic_5_red,R.drawable.ic_6_red,
R.drawable.ic_7,R.drawable.ic_8,R.drawable.ic_8,R.drawable.ic_9,R.drawable.ic_10,R.drawable.ic_11,R.drawable.ic_12
,R.drawable.ic_13,R.drawable.ic_14,R.drawable.ic_15,R.drawable.ic_16,R.drawable.ic_17,R.drawable.ic_18,R.drawable.ic_19,R.drawable.ic_20,
R.drawable.ic_21,R.drawable.ic_22,R.drawable.ic_23,R.drawable.ic_24,R.drawable.ic_25};
While you call super(act, R.layout.custom_row); (without passing the objects), you need to override getCount() method, otherwise your adapter can't figure out how many items you have, and this is why there is no call of getView() method.
#Override
public int getCount(){
return img.length;
}
The first problem I see is your Layout.
<ListView
android:id="#+id/listvv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:divider="#b4be"
android:dividerHeight="2dp"></ListView>
<LinearLayout
android:id="#+id/ad_holder"
android:layout_width="fill_parent"
Your ListView has no room left because the bottom linear layout is using FILL_PARENT (which is deprecated btw, use MATCH_PARENT instead).
Try making your ListView height (and width) to be both MATCH_PARENT. And then deal with the "Ad".
You could have the LinearLayout replaced by a RelativeLayout and have the Ad pin at the bottom of its parent and below the listview.
Second: Why are you using an ArrayAdapter<String> if you're internally using an array of int.
Third: since you're using the wrong type of adapter, you're not correctly implementing it, you need to override more methods (getCount() for example), to tell the underlying adapter: hey, this is the number of items we have.
Since you're not using the provided array of strings, but your custom array of ints that you pass during construction, try overriding getCount() and return the size of your int array instead.
I this there is a issue in your Adapter class, Try this, But keep in mind that there are cleaner ways of writing this same code,
public class CustomAdapter extends ArrayAdapter<Integer> {
int[] img;
Context context;
ImageButton imageButton;
public CustomAdapter(Context context, Integer [] images) {
super(context, R.layout.custom_row, images);
this.context=context;
this.img=images;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d("getView","Called!");
View row = convertView;
if(row==null){
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.custom_row, parent, false);
}
imageButton = (ImageButton) row.findViewById(R.id.preview);
imageButton.setImageResource(img[position]);
Log.d("added",position+"");
if (getSelectedcolor() == 0) {
imageButton.setColorFilter(Color.RED);
setSelectedcolor(Color.RED);
} else {
imageButton.setColorFilter(Color.parseColor(colorToHexString(getSelectedcolor())));
}
return row;
}
}
I can include six buttons and displays correctly as .
Now I want to include more than six buttons in scrollable view, but I can't handle it for matching available space, creating 2 rows (or columns if portrait).
Can you provide some way to achieve this?
References:
I have a composed button created using the following code:
public class ImageButtonText extends RelativeLayout {
ImageButton button;
TextView label;
Holder holder;
private void init() {
LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
li.inflate(R.layout.big_button, this, true);
button = (ImageButton) findViewById(R.id.button);
label = (TextView) findViewById(R.id.label);
/*initialise button and label*/
}
}
and the following xml:
<?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:layout_margin="#dimen/component_margin">
<ImageButton
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/text_box"
android:scaleType="fitCenter"/>
<TextView
android:id="#+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:layout_margin="#dimen/component_margin"
android:gravity="center"
android:text="Sample"
android:textSize="#dimen/text_size"/>
</RelativeLayout>
finally add to the main layout using:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center">
<ImageButtonText
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
custom:buttonBackground="#drawable/states_green"
android:src="#drawable/ic_safe_call"
android:contentDescription="#string/btn1_info"
android:text="#string/btn1text"
android:textColor="#color/text_green" />
<ImageButtonText
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
custom:buttonBackground="#drawable/states_red"
android:src="#drawable/ic_private_call"
android:contentDescription="#string/btn2_info"
android:text="#string/btn2text"
android:textColor="#color/text_red" />
</LinearLayout>
NOTES
May be a different approach also. My final goal is to display multiple buttons (each containing a stretched image and bottom aligned text) in two rows if portrait or three columns if landscape. All this wrapped in scrollable view.
UPDATE:
I solved using RecyclerView :D Thanks everyone
An easy and dynamic approach would be to create a custom List of buttons and put it into a GridView with 2 Colums resp. Rows.
This adapter i did for my navigation has an icon and a text, maybe it helps you. The icon is on the Left side as you can read in this line: holder.textView.setCompoundDrawablesWithIntrinsicBounds(item.get_icon(), 0, 0, 0); Te second one would be the icon above text.
Anyway, I think you will need a custom layout, wich you can easily create doing a new xml file with a Relative or LinearLayout and put an ImageView and a TextView into it and give as a parameter in constructor layoutResourceId.
The height of a listItem you can define in this layout xml file.
The GridView you can Configure different for Landscape and Portrait
In landscape mode the layout from the layout-land/ will be used
In portrait mode the layout from the layout-port/ will be used
public class NavigationAdapter extends ArrayAdapter<NavItem> {
List<NavItem> data;
Context context;
int layoutResourceId;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
NavHolder holder;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new NavHolder();
holder.textView = (TextView)row.findViewById(android.R.id.text1);
row.setTag(holder);
}
else
{
holder = (NavHolder) row.getTag();
}
NavItem item = data.get(position);
holder.textView.setText(item.get_title());
holder.textView.setCompoundDrawablesWithIntrinsicBounds(item.get_icon(), 0, 0, 0);
//holder.textView.setCompoundDrawablePadding(10);
return row;
}
public NavigationAdapter(Context context, int layoutResourceId, List<NavItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
static class NavHolder
{
TextView textView;
}
}
EDIT: This problem has been resolved, so the code in my original post does not apply anymore. Thanks to everyone who contributed.
First off, I have checked other similar questions but they either don't match mine or use the BaseAdapter. What I'm trying to do is display a text-image combination as part of a GridView. The actual app is larger, but my problem is that the GridView is blank in the very first activity!
I'd appreciate if someone can take a quick look at it and tell me what's wrong.
Code for layout file used for GridView elements:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="#+id/iv_grid"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/tv_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
Layout file of first Activity:
<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="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".CategoriesActivity" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="54dp"
android:text="Select a category to learn more" />
<TextView
android:id="#+id/tv_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="26dp"
android:text="Lessons from History"
android:textSize="18sp" />
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textView2"
android:layout_marginTop="25dp"
android:numColumns="3" >
</GridView>
</RelativeLayout>
And finally, the Java file:
package com.example.historicpersonalities;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
public class CategoriesActivity extends Activity {
GridView gv_categories;
public int selected; //which category is selected [0-4]?
String[] data; //holds the data for GridView
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_categories);
populate();
selected = -1;
gv_categories = (GridView) findViewById(R.id.gridView1);
gv_categories.setAdapter(new MyAdapter(this,
android.R.layout.simple_expandable_list_item_1));
gv_categories.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int index,
long arg3) {
}
});
}
class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.layout_grid_scheme, null);
TextView item = (TextView) findViewById(R.id.tv_grid);
item.setText(data[position]);
ImageView img = (ImageView) findViewById(R.id.iv_grid);
img.setImageResource(R.drawable.dummy);
Log.d("ankush", ""+position);
return v;
}
}
private void populate() {
data = new String[5];
data[0] = "Writers";
data[1] = "Painters";
data[2] = "Conquerors";
data[3] = "Chemists";
data[4] = "Actors";
}
}
I think the problem is the height of your gridView. GridView is a scrollable container and can contain any amount of content in any height. Try to set background color to your gridView and you will see, that there is no gridview on the screnn.
It's because you use wrap_content for gridview, but it's incorrect.
If I'm not wrong, it seems that in your constructor you don't pass any data to the adapter.
public MyAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
In this code snippet, your are using ArrayAdapter (Context context, int textViewResourceId) which initialize an empty arraylist as the objects to represent in the GridView.
public ArrayAdapter(Context context, int textViewResourceId) {
init(context, textViewResourceId, 0, new ArrayList<T>());
}
Therefore your GridView should be empty. In addition to that, it seem you didn't properly implement the getView.(findViewById() parts should be handled as shown in the Opiatefuchs's answer)
If you want to extend ArrayAdapter, you should be calling a constructor which takes an array of objects as a parameter. (Of course there are many ways to make a custom adapter you can extend BaseAdapter or while extending ArrayAdapter you can override some other methods)
This way it should work:
class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context context, int textViewResourceId, String[] objects) {
super(context, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.layout_grid_scheme, null);
} else {
view = convertView;
}
TextView item = (TextView) view.findViewById(R.id.tv_grid);
item.setText(getItem(position));
ImageView img = (ImageView) view.findViewById(R.id.iv_grid);
img.setImageResource(R.drawable.dummy);
}
}
Don´t know if this causes the problem, but You have to set Your TextView and ImageView in Your adapter like this:
TextView item = (TextView) v.findViewById(R.id.tv_grid);
item.setText(data[position]);
ImageView img = (ImageView) v.findViewById(R.id.iv_grid);
img.setImageResource(R.drawable.dummy);
EDIT
First of all, the best way is to combine all three solutions. BUT, I have seen another issue in Your xml layout: You put the same id to the TextView inside Your GridView Element xml and Your Activity layout xml. Both TextViews got id="#+id/tv_grid" . This could never work, change the id´s to different ones
My GridView contains columns of fixed width, with fixed horizontal spacing. If there are not enough columns to fill the screen horziontally, I would like my GridView's width to wrap to its contents, and to center vertical in the screen.
However, regardless of the number of columns I use, the GridView's width grows to fill the screen. The attached image shows this, where the green GridView fills the screen horizontally, despite having only 3 columns and its width being set to "wrap_content".
public class Temp extends Activity
{
private GridView grid;
private int columnWidth = 80;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
View view = getLayoutInflater().inflate(R.layout.gridview, null);
grid = (GridView) view.findViewById(R.id.grid);
grid.setColumnWidth(columnWidth);
grid.setAdapter(new GridAdapter());
setContentView(view);
}
class GridAdapter extends BaseAdapter
{
public GridAdapter()
{
}
public int getCount()
{
return 3;
}
public Object getItem(int position)
{
return null;
}
public long getItemId(int position)
{
return position;
}
public View getView (int position, View convertView, ViewGroup parent)
{
View ret;
if (convertView == null)
{
ret = new ImageView(Temp.this);
ret.setLayoutParams(new GridView.LayoutParams(columnWidth, 100));
ret.setBackgroundColor(Color.WHITE);
}
else
{
ret= convertView;
}
return ret;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#FF0000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="#+id/grid"
android:background="#00FF00"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="auto_fit"
android:verticalSpacing="2dip"
android:horizontalSpacing="2dip"
android:stretchMode="columnWidth"
android:gravity="center">
</GridView>
</RelativeLayout>
GridView is extremely annoying with this kind of stuff to say the least. In your case, the issue is that saying auto_fit is essentially telling GridView to always fit it horizontally unfortunately. What you could try is to center the individual ImageViews in the row. But then this requires you to change how you have it set up. Rather than have the columns auto fit, just have 1 item per row, but inflate a LinearLayout that has the orientation as horizontal. Then center the Linear Layout with the ImageViews also in it in each row. Hopefully that provides some ideas.
Simply add two empty views at left and right of GridView with weight = 1 and assign 0.5 weight to GridView. Eg.
<LinearLayout
android:layout_width="fill_parent"
android:gravity="center"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<GridView
android:id="#+id/myGridView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="2"
android:scrollbars="none"
android:verticalSpacing="10dp" >
</GridView>
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
The layout suggested above did not work for me.
In the end I found it easiest to achieve the results you want by programatically setting the width and X location of the grid -- using the setX(float) method to center the grid.
I know there is an old question, but this is the answer:
public class GridViewEx extends GridView {
//private int mRequestedNumColumns = 0;
public GridViewEx(Context context) {
super(context);
}
public GridViewEx(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridViewEx(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int numcol=getNumColumns();
int numitems=getAdapter().getCount();
if(numitems<numcol){
int width = (numitems * getColumnWidth())
+ ((numitems -1) * getHorizontalSpacing())
+ getListPaddingLeft() + getListPaddingRight();
setMeasuredDimension(width, getMeasuredHeight());
}
}
}
And when you add or delete elements from your adapter you have to call:
adapter.notifyDataSetChanged();
gridView.invalidate()