I'm trying to make a variant of the default "Scrolling View" interface on android. Basically the exact same, but with the blue page on top starting at 90% height, and a few options in the bottom white page. To do this, since I read you can't put heights in percentages, I used this code in the main and only activity:
//To fix the height to the right level
Resources res = getResources();
AppBarLayout app_bar = findViewById(R.id.app_bar);
float heightDp = (float)getResources().getDisplayMetrics().heightPixels / 100 * 87; //The percentage
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)app_bar.getLayoutParams();
lp.height = (int)heightDp;
So the app project is just the default Scrolling Activity sample (CoordinatorLayout and NestedScrollView) + the above code.
Problem:
it flickers and sometimes bounces quite a lot when flinging up and down on many devices. Especially on Huawei ones, for some reason.
It doesn't get better adding "snap" in app:layout_scrollFlags.
It also happens when using demo applications like cheesesquare.
I also tried converting the NestedScrollView to a ConstraintLayout, but that made it so you can't scroll up from the bottom page (from the white space) anymore.
Any wisdom to share?
Sorry for the long question. Thanks in advance.
Related
Using the ViewPager view from the Android support library, the default setup shows one page at a time, with a large margin between each item - ie, if your view is about half the width of your activity there's space on either side, and as you swipe the next one in there's space there too.
ViewPagers have a method, setPageMargin(), that lets you specify an offset to adjust the margin size between pages, and I'm using it to specify a negative margin so that it pulls the pages closer together. However, obviously the amount you need to pull in these margins varies according to the screen dimensions.
So, I'm looking for a smarter way: is there a way to tell the ViewPager "I want no margins at all, making the views in my ViewPager butt up against each other"?
Thank you!
I don't know if there's a smarter way, but your way should work if all pages have the same width. Try something like this:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
// getActivity().getWindow... if inside a Fragment
yourViewPager.setPageMargin((yourPageWidth - dm.widthPixels) / 2);
is there a way to move the whole screen content outside the screen bounds, with titlebar and all, on the left for example, i tried
content = ((LinearLayout) act.findViewById(android.R.id.content)
.getParent());
to get the screen content and add a margin to it
FrameLayout.LayoutParams pr = (android.widget.FrameLayout.LayoutParams) content
.getLayoutParams();
pr.rightMargin = xOffset;
content.setLayoutParams(pr);
but it doesnt work, the margin appears but the content is not moved just resized to fit the screen, anyone know how to do this the simple way?
you can set the margin in negative(-) values.
for example if your want the layout to move upper use this:
android:marginTop = "-50dip or more u can put"
Are you trying to flip between views? As in, moving that layout off the screen to show another one? If so you should look at using a widget called ViewFlipper which will do exactly as you need. It can also be animated etc.
http://developer.android.com/reference/android/widget/ViewFlipper.html
I used to have an Activity that would use no ActionBar. The layout is a RelativeLayout with width and height simply matching the parent. It allowed users to drag around buttons using parts of this code in the onTouch event:
MarginLayoutParams marginParams = new MarginLayoutParams(v.getLayoutParams());
int left = (int) event.getRawX() - (v.getWidth() / 2);
int top = (int) event.getRawY() - (v.getHeight());
marginParams.setMargins(left, top, 0, 0);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
v.setLayoutParams(layoutParams);
All dandy—the button moves just below the finger and is placed correctly at the position on screen. Now, however, I enabled the ActionBar, and suddenly when clicked, the button moves ~30 pixels below the finger. To illustrate this behavior, here's what I used to have (on the left) and what happens right now (on the right):
I assume this is because the ActionBar now displaces everything by its own height. Of course, I do not want this to happen, or at least correct this, so:
How can I shift the placement in setMargins() according to the actual size of the ActionBar without using a hardcoded value?
How can I prevent the ActionBar from shifting everything in the first place? Put differently, how can I ensure my button is placed relative to the ActionBar's bottom line and directly where the finger points?
This is what I want:
(I used an approach is my code and it works. I am going to tell you the same here)
I think setMargin() is not such a clever thing to use here. Instead you can use setX() and setY() methods.
Whenever one switches over from a full screen activity to the one with Action Bar, one runs into such problem.
You will need to adjust for the Action Bar height. Instead of using getLayoutParams(), use getLocationInWindow() or getLocationOnScreen(). Since getRawX() and getRawY() work with screen positions of the view, these APIs should be used.
I have a layout which I want to slide down, but not entirely so you can still see a "scroll back up" text. So how I want to do this:
get the dimensions of the device. Put paddingTop = screenHeight - 7dp (for the text). Is this possible? I've tried with layoutparams too but then everything in the layout resized, including the "scroll back up" text.
What is the best way of doing this?
You could use Animation to accomplish this task.
A working example using animation with ViewFlipper can be found here.
I am facing a weird behavior regarding the subject.
I have a very simple layout containing only an empty RelativeLayout.
Once I have input form the user this relative layout is filled with square tiles to achieve a mosaic-like effect. Each tile is made by a FrameLayout containing two images (only one is drawn at any given time). It is not possible for me to put the tiles in the XML layout because I do not know in advance how many of them I will need.
In the onSizeChanged of my relative layout, I force a resize on all the tiles to fit the new size.
The code is something like this:
public void resizeTiles(int w, int h) {
int l1 = w / X; int l2 = h / Y;
int tileS = (l1 <= l2 ? l1 : l2);
android.view.ViewGroup.LayoutParams lp;
for (Tile t : myTiles) {
lp = t.getLayoutParams();
lp.width = tileS;
lp.height = tileS;
}
}
In my manifest file I have the following:
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="4"
/>
Thus, target system is 1.6.
So far so good, this is working like a charm ... but only on 2.2.
The same binary placed on emulator 2.1-update1 or previous is giving me back an empty layout (I also tried a couple of physical devices, same result).
Debugging, I tracked down the problem is in the resize; commenting out width and height assignments I see the tiles but with distorted proportions.
Any suggestion on how to make this working ?
Thanks in advance.
onSizeChanged() is called late in the layout process, once the final size has been determined. There may already have been some layout passes that have happened down through the hierarchy at that point.
Basic answer is: layout params are for telling the view's parent its layout params prior to is performing a layout. If they change, the layout must be invalidated to perform a new complete layout with the new params. You should never change these in the middle of a layout.
The best thing to do is just write your own layout manager. (If you are doing layout of tiles, RelativeLayout does a ton more stuff that you don't need, making it a lot less efficient than necessary.) It is actually not very hard to write a simple layout manager.
You can use the simple layout managers in the framework as a guide:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/AbsoluteLayout.java
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/FrameLayout.java
(Note that even these are a lot more complicated than you probably need, since they are intended to be general purpose for the layouts they are implementing. We really should have an API demo of a custom layout that is truly simple.)