I am using following code to show the GirdView items.
<GridView
android:id="#+id/gridView"
android:gravity="center_horizontal"
android:layout_below="#+id/searchLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" />
Each GridItem (ImageView) is of size 92dp
What i want is to show only 3 Columns or 3 images each Row and each Top, bottom ,left right all needs to be perfectly aligned and equal.
Below is the result of above code.
It can be seen that spaces on left and right of the grid are very less as compared with the ones in between images and also between rows are very small.
Secondly, I am using 92dp. above is the result of S3, but when i use small screen the 3rd image doesn't get fit like in 320 dp screen.
Shouldn't using "dp" automatically adjust according to screen size?
I think this code will help you
try it :-
GridView
android:id="#+id/grid_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="3"
android:gravity="center"
android:stretchMode="columnWidth"
android:background="#000000"/>
In xml of GridView
<GridView
android:id = "#+id/gridViewSms"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:numColumns = "3"
android:horizontalSpacing = "10dp"
android:verticalSpacing = "10dp"
android:gravity = "center"
android:stretchMode ="columnWidth">
In ImageAdapter.java
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private int widthOfScrren;
public Integer[] mThumbIds;
// Constructor
public ImageAdapter(Context c,int ScrrenSize,Integer[] mThumbIds){
mContext = c;
widthOfScrren=ScrrenSize;
this.mThumbIds = mThumbIds;
}
#Override
public int getCount() {
return mThumbIds.length;
}
#Override
public Object getItem(int position) {
return mThumbIds[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView.setImageResource(mThumbIds[position]);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(widthOfScrren / 4,widthOfScrren / 4));
return imageView;
}
}
In Your Activity
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
public class MainActivity extends Activity{
private Integer[] mThumbIds = {
R.drawable.image1 ,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
R.drawable.image6,
R.drawable.image7,
R.drawable.image8,
R.drawable.image9
};
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//found width of Screen for Gridview
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
int densityX = display.getWidth();
GridView grid = (GridView) findViewById(R.id.gridViewSms);
grid.setAdapter(new ImageAdapter(getApplicationContext(), densityX, mThumbIds));
grid.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position ,
long id) {
}
});
}
}
I tested it. It works.
In the past, I have used a GridLayout instead of GridViewso that I can keep compatibility back to api v8.
for GridLayout, I wrote a nifty little function which is placed in the activity to dynamically stretch/space the items in the grid to fill the view evenly. I wrote about it here:
https://stackoverflow.com/a/15341447/2066079
I've also copied the code below for your convenience:
public void fillview(android.support.v7.widget.GridLayout gl)
{
Button buttontemp;
//Stretch buttons
int idealChildWidth = (int) ((gl.getWidth()-20*gl.getColumnCount())/gl.getColumnCount());
for( int i=0; i< gl.getChildCount();i++)
{
buttontemp = (Button) gl.getChildAt(i);
buttontemp.setWidth(idealChildWidth);
}
}
(The 20 is for the internal and external padding and margins. This could be done more universally, but this is far cleaner)
Then it can be called like this:
android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout)findViewById(R.id.buttongrid);
ViewTreeObserver vto = gl.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {#Override public void onGlobalLayout()
{
android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout) findViewById(R.id.buttongrid);
fillview(gl);
ViewTreeObserver obs = gl.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
}});
It must be done with an observer because we need to wait for the view to be drawn before we call the views.
Please try this code :
Grid.xml :
<GridView
android:id="#+id/photo_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:numColumns="3" />
Your custom xml file for photo :
<ImageView
android:id="#+id/img_photo"
android:layout_width="#dimen/grid_photo"
android:layout_height="#dimen/grid_photo"
android:scaleType="fitXY"
android:layout_margin="5dp"
android:src="#drawable/ic_launcher" />
NOTE : Here i recommend to use different dimension for image size instead of fixed 92dp. So, by using dimens.xml you can get exact width and height for different resolution also with same space from all side in Gridview.
I have gone through the same problem a long time ago & get solved by
this:
You can do some change attributes as below in
Gridview:
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="#+id/rltop"
android:fadingEdge="none"
android:fitsSystemWindows="true"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:soundEffectsEnabled="true"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" >
</GridView>
Get your Screen Size & Width by:
Display display= ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
myapp.screen_width = display.getWidth();
myapp.screen_height = display.getHeight();
And The Most Important thing:
In your GridAdapter class -> in getView() method:
call below method to target devices with different resolution:
public void screenResolutions(int screen_width,int screen_height, RelativeLayout relativeLayout)
{
if((myapp.screen_width == 240)&&(myapp.screen_height==320))
{
// relativeLayout.getLayoutParams().height=(myapp.screen_height-(35+General.getStatusBarHeight(cntxt)))/3;
relativeLayout.getLayoutParams().width=(myapp.screen_width)/3;
}
else if((myapp.screen_width== 720)&&(myapp.screen_height==1280))
{
// relativeLayout.getLayoutParams().height=(myapp.screen_height-(107+General.getStatusBarHeight(cntxt)))/3;
relativeLayout.getLayoutParams().width=(myapp.screen_width)/3;
}
else if((myapp.screen_width== 320)&&(myapp.screen_height==480))
{
// relativeLayout.getLayoutParams().height=(myapp.screen_height-(47+General.getStatusBarHeight(cntxt)))/3;
relativeLayout.getLayoutParams().width=(myapp.screen_width)/3;
}
else if((myapp.screen_width == 480)&&(myapp.screen_height==800))
{
// relativeLayout.getLayoutParams().height=(myapp.screen_height-(71+General.getStatusBarHeight(cntxt)))/3;
relativeLayout.getLayoutParams().width=(myapp.screen_width)/3;
}
else if((myapp.screen_width == 768)||(myapp.screen_height==1280))
{
// relativeLayout.getLayoutParams().height=(myapp.screen_height-(114+General.getStatusBarHeight(cntxt)))/3;
relativeLayout.getLayoutParams().width=(myapp.screen_width)/3;
}
else if((myapp.screen_width == 540)&&(myapp.screen_height==960))
{
// relativeLayout.getLayoutParams().height=(myapp.screen_height-(80+General.getStatusBarHeight(cntxt)))/3;
relativeLayout.getLayoutParams().width=(myapp.screen_width)/3;
}
else if((myapp.screen_width == 1080)||(myapp.screen_height==1920))
{
// relativeLayout.getLayoutParams().height=(myapp.screen_height-(160+General.getStatusBarHeight(cntxt)))/3;
relativeLayout.getLayoutParams().width=(myapp.screen_width)/3;
}
}
Where relativelayout = layout which consists ImageView.
You also have to change your height & width of imageview to target
multiple resolutions as below:
put this in your imageview:
android:layout_width="#dimen/image_width"
android:layout_height="#dimen/image_height"
Put this:
In values folder values-hdpi => dimens.xml(480x800)
<dimen name="image_width">92dp</dimen>
<dimen name="image_height">92dp</dimen>
In values folder values-mdpi => dimens.xml(320x480)
<dimen name="image_width">64dp</dimen>
<dimen name="image_height">64dp</dimen>
In values folder values-sw360dp-notlong-hdpi => dimens.xml(540x960)
<dimen name="image_width">114dp</dimen>
<dimen name="image_height">114dp</dimen>
In values folder values-sw360dp-xhdpi => dimens.xml(720x1280)
<dimen name="image_width">138dp</dimen>
<dimen name="image_height">138dp</dimen>
In values folder values-sw360dp-notlong-xhdpi => dimens.xml(768x1280)
<dimen name="image_width">184dp</dimen>
<dimen name="image_height">184dp</dimen>
Have you try default demo given by Developer site?
this demo clear shows all the images with equal height and width and with equal space around it.
Please also check this Example for GridView.
Please let me know if its not helping you.
Enjoy Coding... :)
Related
So i have a recyclerview like this :
as you can see, the screen width is not enough for displaying all the text nicely, so i need to add horizontal scroll so user can scroll horizontally and vertically at the same time, how do i do this?
Use HorizontalScrollView with LinearLayout as child. Set it's Orientation to horizontal and add your dynamic views to it.
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<LinearLayout
android:id="#+id/ll_main"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">
// Add your dynamic views to this layout.
</LinearLayout>
</HorizontalScrollView>
You can use this in your row layout :
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
//Your layout item here
</HorizontalScrollView>
You can add android:scrollHorizontally="true" in your TextView
If there are more than one view in your list item, you can use HorizontalScrollView
Put vertical RecyclerView inside HorizontalScrollView like below.
<HorizontalScrollView
android:fillViewport="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/tasks_recycler_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"/>
</HorizontalScrollView>
Also the root element of the item view for the RecyclerView has to have width wrap_content not match_parent, by setting it's width to wrap_content it allows it to expand the width of its parent which in this case would be the RecyclerView.
Now in the item view either give wrap_content or fixed widths to the inner views which in your case are the views to display "No", "Wonum", "Item num", "Quantity" and "UOM". By giving inner views fixed or wrap_content option they will expand automatically or according to the given width hence expanding their parent.
Try this
val linearLayoutManager = LinearLayoutManager(this)
linearLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
selected_recycler_view.layoutManager = linearLayoutManager
adapter = TAdapter(this, existing.selectedArrayList)
Use this layout manager to allow horizontal scrolling of long items in a vertical LinearLayoutManager.
import android.content.Context;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class FullScrollLayoutManager extends LinearLayoutManager {
private int offset;
private int maxOffset;
public FullScrollLayoutManager(Context context) {
super(context);
}
#Override
public void onLayoutCompleted(RecyclerView.State state) {
super.onLayoutCompleted(state);
int n = getChildCount();
offset = 0;
maxOffset = 0;
int ownWidth = getWidth();
for(int i=0; i<n; ++i) {
View view = getChildAt(i);
int x = view.getRight();
if(x>ownWidth) maxOffset = Math.max(maxOffset,x-ownWidth);
}
}
#Override
public boolean canScrollHorizontally() {
return true;
}
#Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
if(dx<0) {
if(-dx>offset) dx = -offset;
}
else
if(dx>0) {
if(dx+offset>maxOffset) dx = maxOffset-offset;
}
offsetChildrenHorizontal(-dx);
offset += dx;
return dx;
}
}
I have a Gridview where I set some items from an array of string.
The code works fine, but I have a problem with it.
Everytime I add items, it "add" 10 of them and instead of jumping to the item 11, it go back to the first one. So the final result is something like:
1. 1
2. 2
3. 3
4. 4
5. 5
6. 6
7. 7
8. 8
9. 9
10. 10
11. 1
12. 2
...
As I've seen, when I navigate up/down it restart loading the data from the beggining.
Could somebody help me please? I don't know where the problem can be.
CustomGridViewActivity.java:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
public class CustomGridViewActivity extends BaseAdapter {
private Context mContext;
private final String[] gridViewString;
private final String[] gridViewImageId;
public CustomGridViewActivity(Context context, String[] gridViewString, String[] gridViewImageId) {
mContext = context;
this.gridViewImageId = gridViewImageId;
this.gridViewString = gridViewString;
}
#Override
public int getCount() {
return gridViewString.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View convertView, ViewGroup parent) {
View gridViewAndroid;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
gridViewAndroid = new View(mContext);
gridViewAndroid = inflater.inflate(R.layout.gridview_layout, null);
TextView textViewAndroid = (TextView) gridViewAndroid.findViewById(R.id.android_gridview_text);
ImageView imageViewAndroid = (ImageView) gridViewAndroid.findViewById(R.id.android_gridview_image);
textViewAndroid.setText(gridViewString[i]);
Picasso
.with(mContext)
.load(gridViewImageId[i])
.fit() // will explain later
.into((ImageView) imageViewAndroid);
//imageViewAndroid.setImageResource(gridViewImageId[i]);
} else {
gridViewAndroid = (View) convertView;
}
return gridViewAndroid;
}
}
gridview_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/android_custom_gridview_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="#+id/android_gridview_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="15dp" />
<TextView
android:id="#+id/android_gridview_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="12sp" />
</LinearLayout>
content_main.xml:
<GridView
android:id="#+id/grid_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="90dp"
android:gravity="center"
android:numColumns="auto_fit"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true" />
Common.java:
//SearchPanel
static String[] gridViewString = new String[30];
static String[] gridViewImages = new String[30];
MainActivity.java:
public void Search() {
//GridView
CustomGridViewActivity adapterViewAndroid = new CustomGridViewActivity(MainActivity.this, Common.gridViewString, Common.gridViewImages);
androidGridView=(GridView)findViewById(R.id.grid_view);
androidGridView.setAdapter(adapterViewAndroid);
androidGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int i, long id) {
Toast.makeText(MainActivity.this, "GridView Item: " + Common.gridViewString[+i], Toast.LENGTH_LONG).show();
}
});
}
(JUST IN CASE, the data from the "Common" file is added by JSON and it's all different)
In your adapter's getView() method move the lines where you set the text and setup Picasso outside of the if-else block:
if (convertView == null) {
...
} else {
...
}
textViewAndroid.setText(gridViewString[i]);
Picasso
.with(mContext)
.load(gridViewImageId[i])
.fit() // will explain later
.into((ImageView) imageViewAndroid);
return gridViewAndroid;
Right now you're setting the text and image only when the row is being freshly built(convertView being null). As that row view will be recycled(used) for other rows as well, you end up with the old information as you aren't setting up the previously constructed row with new data.
I work in an app in which I want to display in top the month and a left/right arrow for the previous/next months. So far so good.
Down of the month, I want to display a List of names. This is for now. My app is in the first stages.
Looks easy but the list doesn't appear and I can't figure out why.
Here is a preview of the screen.
Here is all the classes and layouts I use.
MainActivity.java
package team.proodeutikiekriksitoumpas;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
public GregorianCalendar month, itemmonth;// calendar instances.
ListView NamesListView, DataListView;
ArrayList<String> NamesFeedList, DataFeedList;
MyNamesAdapter NamesAdapter;
//, DataAdapter;
//public CalendarAdapter adapter;// adapter instance
public Handler handler;// for grabbing some event values for showing the dot marker.
//public ArrayList<String> items; // container to store calendar items which needs showing the event marker
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//DataListView = (ListView) findViewById(R.id.DataListView);
NamesFeedList = new ArrayList<String>();
NamesFeedList.add("Kostis A");
NamesFeedList.add("Apostolis B");
NamesAdapter = new MyNamesAdapter(this, R.layout.name_item_view, R.id.name, NamesFeedList);
NamesListView = (ListView) findViewById(R.id.NamesListView);
NamesListView.setAdapter(NamesAdapter);
/*
DataFeedList = new ArrayList<String>();
DataFeedList.add("Ok");
DataFeedList.add("Ok");
DataAdapter = new ArrayAdapter<String>(this, R.layout.data_item_view, R.id.data, DataFeedList);
DataListView.setAdapter(DataAdapter);
*/
month = (GregorianCalendar) GregorianCalendar.getInstance();
itemmonth = (GregorianCalendar) month.clone();
//Sitems = new ArrayList<String>();
//adapter = new CalendarAdapter(this, month);
handler = new Handler();
//handler.post(calendarUpdater);
TextView title = (TextView) findViewById(R.id.title);
title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
RelativeLayout previous = (RelativeLayout) findViewById(R.id.previous);
previous.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setPreviousMonth();
refreshCalendar();
}
});
RelativeLayout next = (RelativeLayout) findViewById(R.id.next);
next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setNextMonth();
refreshCalendar();
}
});
}
protected void setNextMonth() {
if (month.get(GregorianCalendar.MONTH) == month
.getActualMaximum(GregorianCalendar.MONTH)) {
month.set((month.get(GregorianCalendar.YEAR) + 1),
month.getActualMinimum(GregorianCalendar.MONTH), 1);
} else {
month.set(GregorianCalendar.MONTH,
month.get(GregorianCalendar.MONTH) + 1);
}
}
protected void setPreviousMonth() {
if (month.get(GregorianCalendar.MONTH) == month
.getActualMinimum(GregorianCalendar.MONTH)) {
month.set((month.get(GregorianCalendar.YEAR) - 1),
month.getActualMaximum(GregorianCalendar.MONTH), 1);
} else {
month.set(GregorianCalendar.MONTH,
month.get(GregorianCalendar.MONTH) - 1);
}
}
public void refreshCalendar() {
TextView title = (TextView) findViewById(R.id.title);
//adapter.refreshDays();
//adapter.notifyDataSetChanged();
//handler.post(calendarUpdater); // generate some calendar items
title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
}
/**
* public Runnable calendarUpdater = new Runnable() {
#Override
public void run() {
items.clear();
// Print dates of the current week
DateFormat df = new SimpleDateFormat("yyyy-MM-dd",Locale.US);
String itemvalue;
for (int i = 0; i < 7; i++) {
itemvalue = df.format(itemmonth.getTime());
itemmonth.add(GregorianCalendar.DATE, 1);
items.add("2012-09-12");
items.add("2012-10-07");
items.add("2012-10-15");
items.add("2012-10-20");
items.add("2012-11-30");
items.add("2012-11-28");
}
//adapter.setItems(items);
//adapter.notifyDataSetChanged();
}
};
**/
}
MyNamesAdapter.java
package team.proodeutikiekriksitoumpas;
import java.util.ArrayList;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class MyNamesAdapter extends ArrayAdapter<String> {
// declaring our ArrayList of Strings
private ArrayList<String> objects;
public MyNamesAdapter(Context context, int resource, int textViewResourceId, ArrayList<String> objects) {
super(context, resource, textViewResourceId, objects);
this.objects = objects;
Log.v(null, "listaaaaaaaaa");
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
//return super.getView(position, convertView, parent);
// assign the view we are converting to a local variable
View v = convertView;
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.name_item_view, null);
}
/*
* Recall that the variable position is sent in as an argument to this method.
* The variable simply refers to the position of the current object in the list.
* (The ArrayAdapter iterates through the list we sent it)
*
* Therefore, s refers to the current String object.
*/
String s = null;
if(objects != null) {
s = objects.get(position);
Log.v(null, s);
}
else{
Log.v(null, "null objects");
}
if (s != null) {
Log.v(null, "to textviews");
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView name = (TextView) v.findViewById(R.id.name);
// check to see if each individual textview is null.
// if not, assign some text!
if (name != null){
name.setText(s);
}
}
return v;
}
}
activity_main.xmml
<?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="horizontal" >
<RelativeLayout
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/previous"
android:layout_width="40dip"
android:layout_height="30dip"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true" >
<ImageView
android:contentDescription="#string/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#drawable/arrow_left" />
</RelativeLayout>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dip"
android:textColor="#000000"
android:text="November"
android:textSize="18sp"
android:textStyle="bold" />
<RelativeLayout
android:id="#+id/next"
android:layout_width="40dip"
android:layout_height="30dip"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" >
<ImageView
android:contentDescription="#string/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#drawable/arrow_right" />
</RelativeLayout>
</RelativeLayout>
<ListView
android:id="#+id/NamesListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
name_item_view.xml
<?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="horizontal"
tools:context=".MainActivity" >
<TextView
android:id="#+id/name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text=""
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
Thanks in advance.
there are multiple things here:
activity_main.xml
change android:orientation="horizontal" to "vertical". As you said before, you want the list to be displayed below.
name_item_view.xml
both the layout and the textfield are matching the height. this can be problematic. try having "wrap content" for the text here. also it is not clear on why you actually need a linearlayout wrapped for the textview. maybe try with a simpler version just using the textview. if you want things to be sized, you need something that tells the size. if your list doesnt, then the elements have to. you could have a minimum_height, but it really needs something there to work correctly.
in general you should avoid having listviews using custom length. depending on what exactly you are trying to do it might be perfectly fine to just add those views to a linearlayout if its not that many anyway. otherwise you will have problems very soon. listview is designed to be a size and scrollable - not to be in a scrollcontainer. even though you can make this work, it should be considered a hack.
note: in recyclerview this will not be possible anymore
it might therefore be a good idea to adjust your layout here to accomodate this.
means here:
use all available rest of space for the listview.
now if you like the header to scroll out you have 2 options:
make it a header and use whatever way to make this possible you can find (there are libs, do it yourself, etc)
make it a toolbar and you can just use the appcompat libs simply to make this toolbar go away when people are scrolling. this might currently be the better solution.
hope it helps
Change android:layout_height of ListView from "wrap_content" to some particular value in your xml code
I have created an android application using GridView having three columns. The application is working fine but the problem is that the gridview columns are not completely filling with the view like as shown below.
In html we can put in terms of 100% to make as responsive based on resolution how can we make the same in android
main.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="60px"
android:gravity="center"
android:horizontalSpacing="5px"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="5px" />
mygrid.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="80px"
android:layout_height="100px"
android:background="#444444" >
</ImageView>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#669966"
android:textStyle="bold" >
</TextView>
</LinearLayout>
mygridActivity.java
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class mygridActivity extends Activity {
private GridView g;
Integer[] img = { R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher };
String[] labels = { "Android", "Calender", "Sweety's Home", "New Calender",
"Home", "Star", "GTalk", "Mick", "No Entry" };
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
g = (GridView) findViewById(R.id.gridView1);
g.setAdapter(new ImageAdapter(this));
g.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(getBaseContext(), "Pic : " + (arg2 + 1), 1)
.show();
}
});
}
public class ImageAdapter extends BaseAdapter {
Context mGrid;
public ImageAdapter(Context g) {
this.mGrid = g;
}
public int getCount() {
return img.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = new View(mGrid);
LayoutInflater Inf = getLayoutInflater();
view = Inf.inflate(R.layout.mygrid, null);
} else {
view = convertView;
}
ImageView iv = (ImageView) view.findViewById(R.id.imageView1);
TextView tv = (TextView) view.findViewById(R.id.textView1);
iv.setImageResource(img[position]);
tv.setText(labels[position]);
return view;
}
}
}
Please add the gravity to views within linear layout make it as center rather just making only TextView as center
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center">
//your code
</LinearLayout>
Updates Based on comments
To understand difference between dip/dp and px you can check http://developer.android.com/guide/topics/resources/more-resources.html#Dimension and http://developer.android.com/guide/practices/screens_support.html#density-independence Alternativley you can specify width and height in dimens.xml and values-sw720dp/dimens.xml for mobile and tablet respectively
To handle multiple screen please follow this
Very new to Android and have researched this for a while now but can't quite find the answer. I'm sure there's a simple solution.
I'm getting a NullPointException which is connected to my View characterContainer = findViewById(R.id.icon_container);
As I understand it, it seems I'm trying to implement it in the onCreate() method and as such the layout is not fully ready yet causing characterContainer = null.
So I need to use it in onStart() or onResume() but I'm struggling. This is my code so far:
package harvest.life.game;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
public class HarvestLifeActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//find buttons on screen
Button up = (Button)findViewById(R.id.up);
up.setOnTouchListener(new UpListener());
Button down = (Button)findViewById(R.id.down);
down.setOnTouchListener(new UpListener()); // set as UpListener also for test reasons
Button left = (Button)findViewById(R.id.left);
left.setOnTouchListener(new UpListener()); // set as UpListener also for test reasons
Button right = (Button)findViewById(R.id.right);
right.setOnTouchListener(new UpListener()); // set as UpListener also for test reasons
}
//what up button does
private final class UpListener implements OnTouchListener {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//as long as up button is pressed it will keep moving character up
while (event.getAction() == MotionEvent.ACTION_DOWN)
{
View characterContainer = findViewById(R.id.icon_container);
Drawable walking = getResources().getDrawable(R.drawable.test_circle_red);
int startX = characterContainer.getLeft();
int startY = characterContainer.getTop();
int defaultWidth = characterContainer.getWidth();
int defaultHeight = characterContainer.getHeight();
//create new position for character 1 pixel closer to the top of screen
int newX = startX - 1;
int newY = startY;
//remove character
RelativeLayout view = (RelativeLayout) characterContainer;
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
//re make character in new position created above and assign background as walking forwards animation
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(defaultWidth,defaultHeight);
characParams.leftMargin = newY;
characParams.topMargin = newX;
characterContainer.setLayoutParams(characParams);
characterContainer.setBackgroundDrawable(walking);
}
break;
// when button is let go of
case MotionEvent.ACTION_UP:
RelativeLayout characterContainer = (RelativeLayout)
findViewById(R.id.icon_container);
Drawable standing =
getResources().getDrawable(R.drawable.test_circle);
//assign background back to standing animation
characterContainer.setBackgroundDrawable(standing);
default:
break;
}
return true;
}
}
public void onResume() { // what goes here?
}
}
Do I need to put a sort of function call in the onResume section or do I put the code for what the OnTouchListener does in here?
here's my main:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/game_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="#FFFFFF">
<RelativeLayout
android:id="#+id/side_bar_right"
android:layout_width="50dp"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#000000">
<ImageView
android:contentDescription="#string/movement_button"
android:id="#+id/up"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="top"
android:src="#drawable/up" />
<ImageView
android:contentDescription="#string/movement_button"
android:id="#+id/down"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:src="#drawable/down" />
<ImageView
android:contentDescription="#string/movement_button"
android:id="#+id/right"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="#drawable/right" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/side_bar_left"
android:layout_width="50dp"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#000000">
<ImageView
android:contentDescription="#string/movement_button"
android:id="#+id/left"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="#drawable/left" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/icon_container"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#drawable/test_circle" >
</RelativeLayout >
</RelativeLayout>
Here's what I think you wanted:
package harvest.life.game;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
public class HarvestLifeActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//find buttons on screen
Button up = (Button)findViewById(R.id.up);
//up.setOnTouchListener(new UpListener());
Button down = (Button)findViewById(R.id.up);
//down.setOnTouchListener(new UpListener());
Button left = (Button)findViewById(R.id.up);
//left.setOnTouchListener(new UpListener());
Button right = (Button)findViewById(R.id.up);
//right.setOnTouchListener(new UpListener());
}
public void onDownButtonClick(View view){
while (event.getAction() == MotionEvent.ACTION_DOWN)
{
View characterContainer = findViewById(R.id.icon_container);
Drawable walking = getResources().getDrawable(R.drawable.test_circle_red);
int startX = characterContainer.getLeft();
int startY = characterContainer.getTop();
int defaultWidth = characterContainer.getWidth();
int defaultHeight = characterContainer.getHeight();
//create new position for character 1 pixel closer to the top of screen
int newX = startX - 1;
int newY = startY;
//remove character
RelativeLayout view = (RelativeLayout) characterContainer;
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
//re make character in new position created above and assign background as walking forwards animation
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(defaultWidth,defaultHeight);
characParams.leftMargin = newY;
characParams.topMargin = newX;
characterContainer.setLayoutParams(characParams);
characterContainer.setBackgroundDrawable(walking);
}
}
public void onUpButtonClicked(View view){
RelativeLayout characterContainer = (RelativeLayout)
findViewById(R.id.icon_container);
Drawable standing =
getResources().getDrawable(R.drawable.test_circle);
//assign background back to standing animation
characterContainer.setBackgroundDrawable(standing);
}
}
As you can see, I put your 'down' code in a function, and your 'up' code in another function. Then, in the xml, add android:onClick="onButtonDownClick" to the down button. Do the same (except with an 'onButtonUpClick') to your up button. This will cause those functions to be called on click. It's important to note that those functions take a View as an argument.