Android GridView imperfection, how to remove extra white space to the right - android

I have a GridView based calendar. I have the following XML layout with the selector set to null thus android:listSelector="#null" in accordance with advise I have got from this site. Now I am getting a few pixels wide strip to the right of the GridView. Why? I have tried everything I can but to avail. Here is my XML layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<GridView
android:id="#+id/calendar"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:horizontalSpacing="-1px"
android:numColumns="7"
android:stretchMode="columnWidth"
android:gravity="center"
android:verticalSpacing="-1px"
android:listSelector="#null" >
</GridView>
</LinearLayout>
What I get is this picture:

This space is due to imperfect calculation for each row of your grid.
For example your device width is 320 px and you have 7 rows, try any calculation that meets 320 px. If the width of each cell is 45.71428571428571 px, only then it can be reduced.
Other option
apply
android:gravity="center"
property in you grid so that spaces will equally divided from left to right

in my case I had horizontal spacing as 1dp
android:horizontalSpacing="1dp"
so to solve this I just put the right padding as -1dp
android:paddingRight="-1dp"
even though I expected to get a space on the left side due to this , but it worked properly

Try using
android:layout_margin="0dp"
android:padding="0dp"
Also you might have that space allocated for the scroll bar.
And why do you have your vertical and horizontal spacing with negative values?

I had the same problem though in my case I didn't have control over the GridView instance so I couldn't read the column width. Nevertheless I could subclass its container.
This isn't very orthodox but you can override the onMeasure method and add a few pixels. Something like this:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int RIGHT_MARGIN_OVERSIZE_DIP = 6;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = this.getMeasuredWidth()
int overSize = (int)((getResources().getDisplayMetrics().density*RIGHT_MARGIN_OVERSIZE_DIP) + 0.5f);
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width + overSize, MeasureSpec.getMode(widthMeasureSpec));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

grid.setColumnWidth(grid.getColumnWidth()+1);
This will get the current ColumnWidth and add 1 pixel to it.
Remember to use this after onCreateView,since the grid needs to be initialized before that.
Also,your grid view,should use match_parent (height and width).The image/layout in the column should be also match_parent.

Related

How can I get wrap_content or match_parent layout width and height in android?

I want to get my layout or view (not screen size) width an height in some android devices, so how can i do this? For example:
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingRight="8dp"
android:paddingLeft="8dp"
android:id="#+id/layout_scrol_left"/>
I have this layout and i want to get layout width and height size (in dip) in runtime, how can i do that?
First of all you need to take your layout.
LinearLayout ll_left = (LinearLayout)findViewById(R.id.layout_scrol_left);
Now if ll_left is not yet drawn both ll_left.getHeight() and ll_left.getWidth() will return 0.
So you have to get them after your view is drawn:
ll_left.post(new Runnable(){
public void run(){
int height = ll_left.getHeight();
int weight = ll_left.getWidth();
}
});
i think you can use something like
LinearLayout myView =(LinearLayout)findViewById(R.id.layout_scrol_left);
and you can use the methodes below after the UI thread has been sized and laid
myview.getHeight();
myview.getWidth();
hope this helps .
if you problems using the method above take a look at getWidth() and getHeight() of View returns 0

Dimensions of usable space in window (action bar and margin excluded)

Disclaimer: I rewrote most of this question, including its title, because I partially figured it out.
I'd like to maximize the size of the button on all screen sizes, because it looks silly when it is to small. It should look similar to this:
(Sadly, I cannot include a picture, because my reputation is too low.)
But if I turn the orientation of the device, for example, the button matches it's parents width, becoming ugly proportioned.
(Sadly, I cannot include a picture, because my reputation is too low.)
I now have figured out how to get the dimensions of its parent (the LinearLayout) and how to set the button's size. I used the following code:
window is the ID of the LinearLayout containing (only) the button.
this code is located in the onCreate()-method of the MainActivity.
// Adapt button's size to smaller dimension:
final View window = findViewById(R.id.window);
window.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int width = window.getMeasuredWidth();
int height = window.getMeasuredHeight();
int smallerSize;
if (width < height) {
smallerSize = width;
} else {
smallerSize = height;
}
View button = findViewById(R.id.fartButton);
button.setLayoutParams(new LinearLayout.LayoutParams(smallerSize, smallerSize));
window.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
The problem with this approach is, that it doesn't seem to account for padding. The button get's cut off a little bit on the smaller side (in portrait mode its width, in landscape mode its height).
Interestingly, the image inside the button fits the window perfectly. If for example the height gets cut off a bit, the image still is visible in its full height (only some "extra" parts of the button get cut off, like a little border and shadow).
Is there a way to get the maximal size of the button, which would be the size of the window, but without action bar and minus padding, to prevent any part of the button to get cut off?
Your example above "should look similar to this:" does not seem to have loaded, illustration would help...
But you can manage screen proportions pretty well using android:layout_weight
I'm not sure I'm envisioning your exact needs, but you might try something like this:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="X"
android:text=" "
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="button"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="X"
android:text=" "
/>
</LinearLayout>
where different values for X would control the horizontal aspect ratio for your button in a view.
I just figured it out. Was much easier than I thought. Thanks to everyone who answered, though. It helped me a lot on the way!
The padding that is applied to the window can easily be accesed through the getPadding...() methods. I just needed to adjust the part where the width and height get saved:
int width = window.getMeasuredWidth() - window.getPaddingLeft() - window.getPaddingRight();
int height = window.getMeasuredHeight() - window.getPaddingTop() - window.getPaddingBottom();
I thought, that even by manually excluding the padding, the highlight when pressing the button would be cut off, because it is a bit bigger than the button itself. But this is not the case and it works perfectly. The button now gets displayed in its whole glory. ;)
You can overload your onMeasure method to always return a square.
Create a class that extends to Button and include this
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(size, size);
}
Not sure how this will work if you give exact dimensions but it should work if you set width, height to match parent

How to remove the space between rows of grid view in android

In android grid view there is extra space between the rows of grid view. I am not adding any space to the gridview.
here is my xml files
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:horizontalSpacing="5px"
android:numColumns="3"
android:columnWidth="50dip"
android:verticalSpacing="0dip"
android:gravity="center"
/>
and the other xml for the imageview which is adding view to the gridview is
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/singlePhoto"
android:layout_gravity="top"
android:layout_width="145dip"
android:layout_height="145dip"
android:layout_marginTop="0dip"
android:layout_marginBottom="0dip"
>
</ImageView>
In Adapter class the code is
if(mView == null){
mView = mLayoutInflater.inflate(R.layout.newsgridthumbpic, null);
}
ImageView mImage = (ImageView)mView.findViewById(R.id.singlePhoto);
PhotoGridInfoSet mInfo = (PhotoGridInfoSet)details.get(position);
if(mImage != null){
mImage.setTag(mInfo.getPhotoThumbNailString());
mImage.setVerticalScrollBarEnabled(true);
mImage.setVerticalFadingEdgeEnabled(true);
}
}!
The space is between the rows of gridview. I have not added any space anywhere in the code Still the there is vertical spacing.I am not able understand why there is space in between gridview rows. This space is not appearing in the hdpi device/emulator. This problem is in the mdpi and ldpi devices/emulator.
I got the solution for this problem.
To solve this i need to add 1 line in my xml file
android:adjustViewBounds="true"
and after adding this. the space is not appearing now
Just put last 2 lines in gridView
<GridView
android:numColumns="2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/gridView"
android:horizontalSpacing="0dip"
android:verticalSpacing="0dip"/>
Put the following line in ur getView() method...
mImage.setPadding(0, 0, 0, 0);
I hope this will help you.
It looks like your picture is being scaled to fit the column width of 50dp while maintaining the aspect ratio. This is introducing a bunch of unfilled space in the vertical layout. If you want your column to be 50dp wide, the easiest way to work out these spacing issues will be to adjust your imageview to have a width of 50dp and adjust the imageviews height proportional to that.
just check that your "newsgridthumbpic" layout does not contain the extra padding or any background image having a large height that your grid view element.Also double check that you are supplying column_width as 50dip but your "imageview's" width is 145 dip.
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:horizontalSpacing="5px"
android:numColumns="3"
android:columnWidth="50dip"
android:verticalSpacing="0dip"
android:gravity="center"/>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/singlePhoto"
android:layout_width="145dip"
android:layout_height="145dip"
android:scaleType="fitXY">
</ImageView>
Setting android:verticalSpacing in the gridview to negative values.
will remove the vertical space.
(Eg: android:verticalSpacing="-10dp")
test with some number to get the right value
I have another way as a fixing for the same issue while one using RecyclerView.
Just pass the number of SpanCount like I have given 6 in GridLayoutManager(this, 6) and change the SpanCount to reduce or increase the gap between the items in the RecyclerView.
Check this sample code-
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 6);
rvSizes.setLayoutManager(gridLayoutManager);
SizeSelectorAdaptersizeChooserAdapter = new SizeSelectorAdapter(this, sizes);
rvSizes.setAdapter(sizeChooserAdapter);
Hope this will be useful.
Thank you

How to create a view that is bigger than the screen?

Is it possible to create a view that is bigger than the screen?
I need a view that has a bigger width then the screen of the device. I use this view in a rotation animation. During the rotation the parts that were not on the screen before animating the view will become visible.
Is there a way to achieve this effect with the android framework?
Update
I tried to set my parent layout much bigger then the screen and it is working. This will make somethings a little bit uncomfortable but it could work. The next problem now is that my layout still starts at the left side of the screen. I can't think of a method to make the layout to expand itself to the left and the right of the screen.
Ok I got an answer. It is not very nice because it uses a deprecated View class but it works at least on my current testing screen resolution other resolutions are tested tomorrow.
I wrapped the view that I wanted to expand beyond the screen in an absolute layout like this:
<AbsoluteLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true">
<ImageView
android:id="#+id/content"
android:layout_width="600dip"
android:layout_height="420dip"
android:scaleType="centerCrop"
android:layout_x="-200dip"
android:layout_y="60dip"
android:src="#color/testcolor" />
</AbsoluteLayout>
The -200 x coordinate makes the view stick 200dip out of the left side of the screen. If I'm animating the view those parts that are outside the screen will gradually become visible.
E.g. setting negative bottom margin together with setting extra large layout_height (large enough for you) solved the similar issue as for me.
Works fine at least using API 11+ animations/rotations.
Could look like:
android:layout_marginBottom="-1000dp"
android:layout_height="1000dp"
In case anyone still comes up on this page. The key is your root layout, it will only work with a FrameLayout (or the deprecated absolutelayout). Then you have two options to make your child view bigger.
through xml, this is quick and easy but you don't know the actual screen width & height in advance so your off with setting a ridiculously high value for layout_width & layout_height to cover all screens.
Calculate the screen size programatically and make the view's width/height proportional bigger to this..
Also be aware that your bigger view still starts in the top left corner of the screen so to account this you will have to give a negative top & left margin that's half of what you are adding to the view's width/height
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) viewToMakeBigger.getLayoutParams();
int marginLeft = (int) (viewToMakeBigger.getWidth()*0.1);
int marginTop = (int) (viewToMakeBigger.getHeight()*0.1);
params.width = (int) (viewToMakeBigger.getWidth()*1.2);
params.height = (int) (viewToMakeBigger.getHeight()*1.2);
params.leftMargin = -marginLeft;
params.topMargin = -marginTop;
viewToMakeBigger.setLayoutParams(params);
HorizontalScrollView:
http://developer.android.com/reference/android/widget/HorizontalScrollView.html
Layout container for a view hierarchy that can be scrolled by the user, allowing it to be larger than the physical display.
The simple axml below creates an ImageView that is 400dp wider than the screen (even though the layout_width is set to equal the parent's width) using a negative left and right margin of 200dp.
The ImageView is situated 250dp above the top of the screen using a negative top margin, with 450dp of 700dp vertical pixels visible on the screen.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:background="#FFFF0000"
android:layout_height="700dp"
android:layout_marginLeft="-200dp"
android:layout_marginRight="-200dp"
android:layout_marginTop="-250dp"
android:layout_width="match_parent" />
</RelativeLayout>
You can override the views in the onMeasure method. This will set your View dimensions to 1000x1000 px.
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(1000, 1000);
}
Is it possible to create a view that is bigger than the screen?
Why not, you can define the layout_width and layout_height in px(or dip) as you want:
android:layout_width="10000px"
android:layout_height="20000px"
You need to change the size of the window, by getWindow().setLayout. This will increase the size for your window. Since the root layout can be as big as its parent you can then increase the size of the view you want to be bigger than the screen size. It works for me let me know
You can use ViewSwitcher to handle that. Used with Animation and a OnGestureListener looks pretty good.
You can do it programmatically:
FrameLayout.LayoutParams rootViewParams = (FrameLayout.LayoutParams) rootView.getLayoutParams();
rootViewParams.height=displayMetrics.heightPixels+(int)dpToPixels(60);
rootViewParams.width=displayMetrics.widthPixels+(int)dpToPixels(60);
rootView.setLayoutParams(rootViewParams);
rootView.setX(rootView.getX() - dpToPixels(30));
rootView.setY(rootView.getY() - dpToPixels(30));
MUST BE ONLY IN
"public void onWindowFocusChanged(boolean hasFocus)" method.
and
rootView = (RelativeLayout) findViewById(R.id.rootLayout);
Inside "protected void onCreate(Bundle savedInstanceState)" method.
Where yout .xml file is like this:
<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:id="#+id/rootLayout"
tools:context="com.example.Activity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_centerHorizontal="true"
android:layout_margin="30dp"
android:layout_centerVertical="true"
android:layout_height="match_parent">
// Bla bla bla
</RelativeLayout>
and:
public float dpToPixels(float dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}

Calculating the size of a view

The best way to ask this question is to provide an example, so here it is:
<ScrollView>
<LinearLayout
android:id="#+id/main"
android:orientation="vertical"
>
<TextView
android:id="#+id/some_text"
/>
<LinearLayout
android:id="#+id/stretch_me"
/>
<Button
android:id="#+id/i_can_toggle"
/>
<TextView
android:id="#+id/toggle_me"
android:visibility="gone"
/>
<Button
android:id="#+id/finished"
/>
</LinearLayout>
</ScrollView>
This seems fairly simple, but hold on ...
1) I would like the stretch_me layout to take all the remaining space on the screen (and I need its size so I can dynamically populate it from code)
2) I can't change main to RelativeLayout because I would like to toggle toggle_me between gone and visible using the i_can_toggle but need to keep strech_me size the same as before
3) Before changing toggle_me to visible there must be no scroll and finished button must be positioned at the bottom of the screen
Now I have tried many things and the most promising approach was this one with some coding (I was thinking about setting the stretch_me size from code), but I was not able to get the size of the view from my onCreate() method (screen_height - view_height = remaining space).
Any ideas?
Thanks!
Set stretch_me to have these attributes to make it take up the space
android:layout_height="fill_parent"
android:layout_weight="1"
I would like the stretch_me layout to
take all the remaining space on the
screen
Set the height and weight parameters to the following
android:layout_height="fill_parent"
android:layout_weight="1"
I need its size
You can use onmeasure() to measure the view size. http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpec = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
//Similarly for height
}

Categories

Resources