Make HorizontalScrollView hover ViewPager/Fragments - android

Is there any way I can make my HorizontalScrollView (SlidingTabLayout) hover my ViewPager and its fragments instead of displaying them linearly?
<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="vertical"
tools:context="com.zerohora.app.fragments.ContentFragment">
<com.zerohora.app.widgets.SlidingTabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:layout_gravity="top"
/>
</LinearLayout>
Already tried FrameLayout and RelativeLayout, and it didn't work. Swipe stops working after this chang.
Also changed their marginTop, but the ViewPager always get on top of the ScrollView.
The idea here is to hide the HorizontalScrollView (SlidingTab) whener users scrolls a list in a ViewPager fragment.
Thank you

I was able to find a workaround for it:
First bring the view that you want to be on front of the others by calling brinToFront() method:
mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.bringToFront();
Then you can place the view wherever you want. If you want to place it on top but just after the action bar, you can do the following:
// Get viewport's heigth
WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int viewportHeight = size.y;
// Get ActionBar's height
TypedValue tv = new TypedValue();
int actionBarHeight = 0;
if (getActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}
// Get status bar height
int statusBarHeight = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
// Set tabs position
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = -(viewportHeight) + actionBarHeight + statusBarHeight;
mSlidingTabLayout.setLayoutParams(params);
//Redraw display
mSlidingTabLayout.invalidate();
mViewPager.invalidate();

Related

Filling the whole screen with Gridview items

I have a GridView (with 2 columns and 2 rows) and want to stretch the rows to fill the whole screen. It should look the same on all devices.
That means I don't want some empty space under the last row. So I searched a little bit and found a solution to set the minimum height of the GridView dynamically with following code:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
In addition I added these lines of code in my Adapter:
gridView = inflater.inflate(R.layout.act_main_menu_sub, null);
gridView.setMinimumHeight(ActMainMenu.height/2);
But now it looks like this:
The View is scrollable now and the items have the same size. But it doesn't fit on the screen.
Here is the code of my layout including the GridView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layout_main_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#b2b2b2"
android:orientation="vertical">
<!-- android:layout_height="wrap_content" -->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
android:padding="2dp"
app:titleMarginStart="20dp"
app:titleTextAppearance="#style/MyMaterialTheme.Base.TitleTextStyle"
app:titleTextColor="#color/textColorPrimary">
<TextView
android:id="#+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="MASTERFITNESS TRAINERSCHULUNG"
android:textColor="#android:color/white"
android:textStyle="bold|italic"/>
</android.support.v7.widget.Toolbar>
<!--android:columnWidth="160dp"-->
<GridView
android:id="#+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:gravity="center"
android:horizontalSpacing="20dp"
android:numColumns="2"
android:stretchMode="columnWidth"
android:verticalSpacing="20dp"></GridView>
</LinearLayout>
What is the problem here?
The problem with your 2nd screen shots in the height calculation. metrics.heightPixels gives you the full height of the screen, including the toolbar and any margins you have. These should 1st be subtracted out, then divide the screen in half.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
// your layout has 10dp margin (top & bottom) + 20 dp between grid items, 10+10+20=40
int marginSizeDp = 40;
float scale = metrics.density;
int marginSizePx = Math.round (marginSizeDp * scale);
int appBarHeight = getAppBarHeight();
int height = metrics.heightPixels;
int minHt = Math.round((height - marginSizePx - appBarHeight)/2);
gridView.setMinimumHeight(minHt);
Get the toolbar height thanks to AZ13 at https://stackoverflow.com/a/7167086/7292819
// returns height of app bar in pixels
private int getAppBarHeight() {
final TypedArray styledAttributes = getTheme().obtainStyledAttributes(
new int[] { android.R.attr.actionBarSize });
int appBarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
return appBarHeight;
}
Truthfully, if this layout is static (there's only 4 items, no scrolling, little or no changing of the content of each item), I probably wouldn't bother with a GridView & adapter. A RelativeLayout or GridLayout might be better.

Different values of width returned in fragment

I'm trying to determine the screen's width and height to use them in a fragment.
My fragment's layout has the id background.
If inside onViewCreated I use:
background = (RelativeLayout) view.findViewById(R.id.background);
background.post(new Runnable() {
#Override
public void run() {
int width = background.getMeasuredWidth();
int height = background.getMeasuredHeight();
Log.d("askj", width + "+" + height);
}
});
I get 1440+2276
but if I use:
WindowManager windowManager = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
Log.d("askj", width + "+" + height);
or other related methods I get:
1440+2560
I'm using those parameters to set a background and I can clearly see that the whole screen size is not taken if I use the second approach. I don't really want to use that Runnable() so is there any way in which I can solve this ?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="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:id="#+id/background"
tools:context="com.example.home.background.HomeScreen">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/img"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textStyle="bold"
android:layout_centerInParent="true"
android:textSize="22sp"
/>
</RelativeLayout>
You can measure the background View before your activity has added it to its view hierarchy by yourself using measure method.
background = (RelativeLayout) view.findViewById(R.id.background);
background.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
int backgroundHeight = background.getMeasuredHeight();
int backgroundWidth = background.getMeasuredWidth();
In my case I measured an inflated View but it had the width and height set to match_paent.
View view = inflater.inflate(R.layout.table_field_text, null, false);
view.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
int viewHeight = view.getMeasuredHeight();
Use ViewTreeObserver like Below:
background = (RelativeLayout) view.findViewById(R.id.background);
final ViewTreeObserver vto = background.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
//get View Width and height here
int width = background.getWidth();
int height = background.getHeight();
//Call anyfunction which uses width and height here
function(width,height);
//Then remove layoutChange Listener
ViewTreeObserver vto = background.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
vto.removeOnGlobalLayoutListener(this);
} else {
vto.removeGlobalOnLayoutListener(this);
}
}
});

Programmatically resize framelayout

I have something like that:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/photo1"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/photo2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</FrameLayout>
<Fragment>
</Fragment>
</FrameLayout>
And I want to resize that photo2 FrameLayout.
public void setScreenSize() {
Display display = getWindowManager().getDefaultDisplay();
FrameLayout layout = (FrameLayout) findViewById(R.id.photo2);
int screen_height = display.getHeight();
screen_height = (int) (0.60*screen_height);
LayoutParams parms = (LayoutParams) layout.getLayoutParams();
parms.height = screen_height;
}
Unfortunately this doesn't work and I don't know why.
Are you setting the height back to the layout?
public void setScreenSize() {
Display display = getWindowManager().getDefaultDisplay();
FrameLayout layout = (FrameLayout) findViewById(R.id.photo2);
int screen_height = display.getHeight();
screen_height = (int) (0.60*screen_height);
LayoutParams parms = (LayoutParams) layout.getLayoutParams();
parms.height = screen_height;
// Set it back.
layout.setLayoutParams(parms);
}
If you want to change the size of FrameLyaout programmatically then copy and paste this code, its working 100%.
FrameLayout frame1 = (FrameLayout) findViewById(R.id.framelayout1);
frame1.getLayoutParams().height =460;
frame1.getLayoutParams().width = 350;
frame1.requestLayout();

Android: How do I add an element to scrollview below the screen using x and y (and have it scroll)

I'm trying to add an element to a screen in Android using X and Y co-ordinates that's beneath the screen but when it loads the screen won't scroll.
My code for the layout
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="vertical"
android:id="#+id/ScrollView"
android:background="#16A901"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/inner"
android:background="#b200C4"
>
</RelativeLayout>
</ScrollView>
My Java code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xycords);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int maxX = size.x;
int maxY = size.y;
System.out.println("bar maxX "+maxX+" maxY "+maxY);
ScrollView sv= (ScrollView)findViewById(R.id.ScrollView);
RelativeLayout inner = (RelativeLayout)findViewById(R.id.inner);
Button button = new Button(this);
button.setBackgroundResource(R.drawable.black_rect_border_yellow);
button.setText("Test 1 2 3");
button.setX(10);
button.setY(661);//652 is the maxY in my set up so this will obscure part of it
LayoutParams wrap= new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
wrap.setMargins(0, 0, 0, 0);
//wrap.addRule(RelativeLayout.ALIGN_LEFT,R.id.vLine);
//wrap.addRule(RelativeLayout.ALIGN_TOP,R.id.hLine);
inner.addView(button, wrap);
}
I end up with a button where part of it is offscreen but it won't scroll to show the rest.
Any idea what I'm doing wrong?
You must set inner layout_height to a value greater than button y value:
...
inner.addView(button, wrap);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)inner.getLayoutParams();
params.height = 661 + 48;
inner.setLayoutParams(params);

Calculate view measure before display it

I am trying to add views to LinearLayout dynamically as much as it possible (depending on screen width).
I do this before the LinearLayout displays on screen.
My LinearLayout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:background="#666"/>
My view to display in LinearLayout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:background="#999">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:src="#drawable/no_photo"/>
</FrameLayout>
I add views to layout:
int allItems = 50;
int currentItem = 0;
while(currentItem < allItems)
{
FrameLayout view = (FrameLayout) inflater.inflate(R.layout.fl, null);
linearLayout.addView(view);
if (linearLayout.getMeasuredWidth() >= this.getWidth())
{
linearLayout.removeView(view);
break;
}
}
but linearLayout.getMeasuredWidth() and this.getWidth() is 0;
I know, that i must use View.measure method to calculate view size before it became visible, but i don't know where and how it use.
Edit your code as below :
Display display = getWindowManager().getDefaultDisplay();
int maxWidth = display.getWidth();
int widthSoFar=0;
int allItems = 50;
int currentItem = 0;
while(currentItem < allItems) {
FrameLayout view = (FrameLayout) inflater.inflate(R.layout.fl, null);
linearLayout.addView(view);
view .measure(0, 0);
widthSoFar = widthSoFar + view.getMeasuredWidth();
if (widthSoFar >= maxWidth) {
linearLayout.removeView(view);
break;
}
}
Hope this helps you

Categories

Resources