I've a simply layout like following for a custom view:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/someInnerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/iv_arrow"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerHorizontal="true"
android:src="#drawable/arrow"/>
</RelativeLayout>
And this function in my custom view:
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mForceSquareLayout) {
int w = getMeasuredWidth();
int h = getMeasuredHeight();
if (w != h) {
int size = Math.min(w, h);
setMeasuredDimension(size, size);
}
}
}
Any my layout looks like following:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
style="?toolbar_view_theme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorPrimary"
android:elevation="16dp" />
<CustomView
android:id="#+id/wheel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="16dp"
app:square_layout="true"
app:arrow_image="#drawable/ic_arrow_drop_down_white_24dp"
app:background_color="?colorPrimary" />
</LinearLayout>
</layout>
The problem is, that if the square logic does resize the view (which it does in landscape mode), my custom views child iv_arrow is not shown anymore. It looks like my square logic does not relayout the children. Any ideas how to solve this?
I tried requestLayout on the view and on the child with no success...
Related
I got help from links and other links but it didn't help me and my problem was not solved
MY PROBLEM: I have ViewPager with 3 Fragment that 2 of them contain RecycleView with dynamic data!
Now the ViewPage gets the biggest height !!!! I want to set the height of the fragment as the original size!
my code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
style="#style/CardStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.duolingo.open.rtlviewpager.RtlViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_marginTop="#dimen/default_margin_double"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tab_layout" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
style="#style/TabbedCard"
android:layout_width="match_parent"
android:layout_height="#dimen/tabbed_card_tab_layout_height"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabGravity="fill"
app:tabMode="scrollable"
app:tabPaddingTop="#dimen/default_margin_half"
app:tabTextAppearance="#style/investTab" />
</androidx.constraintlayout.widget.ConstraintLayout>
and one of my fragment that contains RecyclerView :
<LinearLayout 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="wrap_content"
android:layout_gravity="center"
android:scrollbarStyle="insideOverlay"
android:orientation="vertical"
tools:context=".mvvm.screens.investment.view.fragment.tabs.RequestListFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/account_list"
style="#style/InvestmentRecyclerView"
android:scrollbarStyle="insideOverlay"
tools:listitem="#layout/investment_request_item"
android:paddingBottom="#dimen/default_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="#+id/loading"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="?attr/cardTitle"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="#+id/view_error"
layout="#layout/view_error"
android:visibility="gone" />
<include
android:id="#+id/view_empty"
layout="#layout/no_investment_found"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
Finally, I Create custom class from ViewPager like this :
public class WrappedHeightTabbedCardViewPager extends NonSwipeableViewPager {
private int currentPagePosition = 0;
public WrappedHeightTabbedCardViewPager(#NonNull Context context) {
super(context);
}
public WrappedHeightTabbedCardViewPager(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
View child = getChildAt(currentPagePosition);
if (child != null) {
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
}
if (heightMeasureSpec != 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void reMeasureCurrentPage(int position) {
currentPagePosition = position;
requestLayout();
}
}
I want to move my layout up when the keyboards shows on my app . I used adjustResize , adjustPan and both of them for the activity but non of them works and it still shows the keyboard on the form and does not move the layout above .
this is my layout :
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
............... my views
</LinearLayout>
</ScrollView>
</RelativeLayout>
how can I make it works ?
try like this
final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > dpToPx(getApplicationContext(), 200)) { // if more than 200 dp, it's probably a keyboard...
// ... do something here
}
}
});
public static float dpToPx(Context context, float valueInDp) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}
andjust add this in your xml
android:id="#+id/activityRoot"
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
**android:id="#+id/activityRoot"**>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
............... my views
</LinearLayout>
</ScrollView>
</RelativeLayout>
I'm facing a strange problem. I have a xml with two RecyclerView and a ViewPager with circle page indicator inside a NestedScrollview. I have used layout_weight and weightSum to show widget on screen. One of RecyclerView has horizontal layout which is scrolling horizontally fine. I want to achieve single vertical scrolling but unfortunately it is not working.
I have used "app:layout_behavior="#string/appbar_scrolling_view_behavior" in xml and "recyclerview.setNestedScrollingEnabled(false)" in java code.
here is my fragment_home.xml
<android.support.v4.widget.NestedScrollView 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:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.e2e.qnamo.fragment.HomeFragment">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10"
android:descendantFocusability="blocksDescendants">
<include
layout="#layout/layout_pager_indicator"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_hot_topic"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_weight="2"
tools:listitem="#layout/hot_topic_row" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_category"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_weight="5"
tools:listitem="#layout/category_row"/>
</LinearLayout>
here is my layout_pager_indicator.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/bannerViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#layout/viewpager_indicator_single_item" />
<com.e2e.qnamo.widget.CirclePageIndicator
android:id="#+id/pager_indicator"
style="#style/CustomCirclePageIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="center|bottom"/>
Seems like every one was busy else where :) Anyway I managed to find solution by myself.
There were three potential problem which causing problem:
Using "weightSum" in parent layout and
ViewPager in layout
ViewPager takes whole screen by default.
I have used "weightSum" to control size of ViewPager and showing other two Recyclerview. To remove "weightSum" I customised ViewPager so that it only takes height of its biggest children. Below are the customised ViewPager code:
public class CustomViewPager extends ViewPager
{
private int mCurrentPagePosition = 0;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for(int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if(h > height) height = h;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void reMeasureCurrentPage(int position) {
mCurrentPagePosition = position;
requestLayout();
}
}
Second step I did that I removed "layout_weight" from both of RecyclerView and set it "layout_height" to "wrap_content" and work done.
Below are the updated layout code:
fragment_home.xml
<android.support.v4.widget.NestedScrollView 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:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
android:fillViewport="true"
tools:context="com.e2e.qnamo.fragment.HomeFragment">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/main_container_margin"
android:layout_marginTop="#dimen/main_container_margin"
android:layout_marginRight="#dimen/main_container_margin"
android:layout_marginBottom="#dimen/main_container_margin"
android:orientation="vertical">
<include
layout="#layout/layout_pager_indicator"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_hot_topic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/recycler_margin_top"
tools:listitem="#layout/hot_topic_row" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_category"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/recycler_margin_top"
android:layout_marginBottom="10dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:listitem="#layout/category_row"/>
</LinearLayout>
layout_pager_indicator.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.e2e.qnamo.widget.CustomViewPager
android:id="#+id/bannerViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#layout/viewpager_indicator_single_item" />
<com.e2e.qnamo.widget.CirclePageIndicator
android:id="#+id/pager_indicator"
style="#style/CustomCirclePageIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="center|bottom"/>
Thats it!!!
I have a RecyclerView as the only child of SwipeRefreshLayout, I want the RecyclerView wrap_content. When I set both of them "wrap_content", it doesn't work. The RecyclerView with fewer items also match_parent. When i delete SwipeRefreshLayout, the RecyclerView will wrap_content. Can anyone help me? My English is poor, Maybe you cann't understand. Anyone can help me? Thank you very much.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_v"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ffff">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff00ff">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
Finally, I work out it. From this Answer
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_v"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ffff">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff00ff"/>
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
The key is to use Layout wrap RecyclerView. Beacause of SwipeRefreshLayout use MeasureSpec.EXACTLY mode measure mTarget size when onMeasure():
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mTarget == null) {
ensureTarget();
}
if (mTarget == null) {
return;
}
mTarget.measure(MeasureSpec.makeMeasureSpec(
getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY));
......
}
And mTarget is the first child view of SwipeRefreshLayout. So this will cause the mTarget always match parent.
private void ensureTarget() {
// Don't bother getting the parent height if the parent hasn't been laid
// out yet.
if (mTarget == null) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (!child.equals(mCircleView)) {
mTarget = child;
break;
}
}
}
}
FrameLayout is used because it is more lightweight.
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp"
tools:itemCount="2"
tools:listitem="#layout/item_msg_detail_text_style" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
I'm trying to make a simple listView with string objects only inside dialog; the problem is the list item is not width match_parent as i set:
the list view is the root element:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ff0000"
android:id="#+id/lvLinks"
android:layout_height="match_parent"/ >
list item:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:padding="7dp"
android:textSize="15sp"
android:background="#0000ff"
android:layout_height="match_parent" />
adapter:
ListView lv = (ListView) findViewById(R.id.lvLinks);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,R.layout.list_item_links,items);
lv.setAdapter(adapter);
I've tested it on many OS, this is not the problem
FIXED:
answer
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ff0000"
android:id="#+id/lvLinks"
android:layout_height="match_parent" />
</LinearLayout>
Why don't you put your ListView inside LinearLayout or RelativeLayout having width match_parent or fill_parent dialog.xml
This may be not exact solution but you can try below xml for your list item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
<TextView
android:id="#android:id/text1"
android:layout_width="match_parent"
android:padding="7dp"
android:textSize="15sp"
android:background="#0000ff"
android:layout_height="wrap_content" />
</LinearLayout>
The proposed answer didn't solve anything for me. The issue actually only showed on MIUI devices, not on Google's stock nor Samsung or OnePlus.
Instead I added the following code to my custom listView constructor:
addOnLayoutChangeListener(this);
And the listener:
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
{
int I = getChildCount();
for(int i = 0; i < I; i++)
{
getChildAt(i).requestLayout();
}
}