A Fragment's height (in a Viewpager) cannot be reduced - android

I have a tablayout with a viewpager that contains four fragments, the first 3 tabs( fragments) works fine. But the last fragment's height cannot be reduced . Its layout contains only an Imageview with fixed size height. but the fragment height is always greater than the imageview. I tried to put the imageview inside a frame layout and linearlayout, trying all height possibilities: match_parent, wrap_content and fixed size height but, it didn't work.
I tried to add maxHeight to the imageview with no luck.
I guessed that the problem may be with the view pager since it may be measuring other fragment's height and stuck with this height, but why other fragments is working fine.So I need your help. Thanks in advance
This is my last fragment layout:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="260dp"
android:maxHeight="260dp"
android:scaleType="centerCrop"
android:src="#drawable/gs350f"/>
And this is the viewpager layout:
<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.support.design.widget.TabLayout
android:id="#+id/car_overview_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="#drawable/rounded_corner"
app:tabGravity="fill"
app:tabIndicatorColor="#android:color/transparent"
app:tabMaxWidth="0dp"
app:tabMode="fixed"
app:tabSelectedTextColor="#color/high" />
<com.myproject.ui.custom.NonSwipeableViewPager
android:id="#+id/overview_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/car_overview_tabs" />
And finally this is NonSwipeableViewPager class:
public class NonSwipeableViewPager extends ViewPager {
public NonSwipeableViewPager(Context context) {
super(context);
}
public NonSwipeableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
#Override public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
}

Related

Vertical RecyclerView reacts to scroll on nested Horizontal RecyclerView

In my activity, I have ViewPager consisting of fragments. I have disabled swipe motion on ViewPager using CustomViewPager.
My fragment layout has Vertical RecyclerView and inside this RecyclerView there are multiple Horizontal RecyclerViews.
To ensure that my AppBarLayout responds to scroll behaviour properly, I have programmatically set nestedScrollingEnabled to false on each Horizontal RecyclerView.
P.S. I'm using recylerview version 25.4.0
The problem is as you can see in gif attached above, to scroll horizontal recyclerview the touch should be perfectly sideways, even for a slightly slant motion on horizontal recyclerview, the vertical recyclerview picks up that event and scrolls the page vertically UP & DOWN. How to resolve this?
CustomViewPager.java
public class CustomViewPager extends ViewPager {
private boolean enabled;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onTouchEvent(event);
}
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
return false;
}
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
}
Fragment Layout
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_productoverview"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/windowBackground"/>
Layout of items inside recyclerview_productoverview(Vertical RecyclerView)
<android.support.constraint.ConstraintLayout
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.support.constraint.ConstraintLayout
android:id="#+id/layout_section_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:background="#ebedff"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<experttag.nurserylive.util.ui.widget.WhitneySemiBoldTextView
android:id="#+id/textview_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TOP FEATURED"
android:textColor="#3f4266"
android:textSize="16sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"
app:layout_constraintVertical_bias="0.19"
android:layout_marginLeft="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginRight="16dp"
app:layout_constraintRight_toRightOf="parent"/>
<experttag.nurserylive.util.ui.widget.WhitneySemiBoldTextView
android:id="#+id/textview_item_viewall"
style="#style/AppTheme.TextLink"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#3f4266"
android:text="#string/btn_view_all_caps"
android:layout_marginRight="16dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBaseline_toBaselineOf="#+id/textview_item_name"/>
</android.support.constraint.ConstraintLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_item_section"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/layout_section_header"/>
</android.support.constraint.ConstraintLayout>
Horizontal RecyclerView: #id/recyclerview_item_section
Solved this using BetterRecyclerView
see demo
read explanation
BetterRecyclerView.java

View animated using CoordinatorLayout and AppBarLayout getting crazy (sometimes)

This thing is getting me nuts.
I have been able to get this behavior (exactly what I want): http://i.imgur.com/PGhL22k.gif
And this is the behavior is has when I scroll down very fast: http://i.imgur.com/kk7icAc.gif and http://i.imgur.com/YNPNiA6.gif
I am sorry but the GIFs are larger than 2Mb and I cannot upload them here...
I want the pagination bar at the bottom to hide the same amount the toolbar does. When scrolling slowly it goes very well, but when fast scrolling it has a really strange behavior as you can see at the GIFs provided above.
This is the layout XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:kiosk="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="#layout/android_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
kiosk:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/vpPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
kiosk:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<include
layout="#layout/paginator_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
kiosk:layout_behavior="carl.fri.fer.views.KioskPaginator.KioskPaginatorScrollBehaviour"/>
</android.support.design.widget.CoordinatorLayout>
The "android_toolbar" include is as follows:
<?xml version="1.0" encoding="utf-8"?>
<carl.fri.fer.views.KioskToolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primaryColor"
android:minHeight="?attr/actionBarSize"/>
And the "paginator_layout" is the following:
<?xml version="1.0" encoding="utf-8"?>
<carl.fri.fer.views.KioskPaginator.KioskPaginator
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/kpPaginator"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:animateLayoutChanges="true"
android:background="#color/primaryColor"
android:clickable="true"
android:orientation="horizontal">
<TextView
android:id="#+id/tvCurrentPage"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center"
android:padding="10dp"
android:textColor="#color/color_pure_black"
android:textSize="17sp"/>
<LinearLayout
android:id="#+id/llMoreOptions"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="#android:color/transparent"
android:gravity="center_vertical"
android:orientation="horizontal"/>
<TextView
android:id="#+id/tvTotalPages"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center"
android:padding="10dp"
android:textColor="#color/color_pure_black"
android:textSize="17sp"/>
</carl.fri.fer.views.KioskPaginator.KioskPaginator>
And the ScrollBehavior is as follows:
public class KioskPaginatorScrollBehaviour extends AppBarLayout.ScrollingViewBehavior {
public KioskPaginatorScrollBehaviour(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof AppBarLayout;
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
float depY = - dependency.getHeight();
depY -= dependency.getY();
Utils.log("dependency", "" + depY);
child.setTranslationY(depY);
return true;
}
}
Inside of every page of the ViewPager, there is a Fragment. And the content of this Fragment is a RecyclerView with dynamic content. All the content from the RecyclerView is loaded from database and images are loaded at runtime.
Can someone please tell me why is this strange behavior happening? How can I fix it?
Thank you in advance...
EDIT 1:
I just spotted the cause of the weird behavior! The ViewPager loads the current page and the adjoining ones. The content of the RecyclerView loads from the Internet and as soon as it is loaded, it goes into the RecyclerView. The ViewPager first loads the current page and then the adjoining ones. If I have scrolled down the current page RecyclerView (Toolbar is hidden) when the 2nd RecyclerView just loads and shows the content, it resets the current page AppBarLayout behavior, so it resets my custom view behavior... How can I fix that? I want to avoid not loading adjoining views..
EDIT 2:
Ok, it happens when loading adjoining pages of ViewPager and also when loading from the Internet images inside the RecyclerView... this is crazy.
So finally resolved your problem - make your custom behavior extending CoordinatorLayout.Behavior instead of ScrollingViewBehavior and it will work as expected. Just set the value to your view's translationY, that is opposite to Y of AppBarLayout:
public class KioskPaginatorScrollBehaviour extends CoordinatorLayout.Behavior<View> {
public KioskPaginatorScrollBehaviour(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof AppBarLayout;
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
float depY = -dependency.getY();
child.setTranslationY(depY);
return true;
}
}

Make RecyclerView to wrap its content when using CardView with square ImageView

I am trying to achieve following structure (image below). As you can see there are two sections with RecyclerViews and CardViews in it. These two sections are divided by two TextViews with Buttons.
Each section should match screen width (minus indent between cards). Each CardView has square ImageView in it. So the height of CardView itself depend on screen width: card_height = screen_width - indent_between_cards + space_for_card_text. To achieve this behaviour I use simple SquareImageView, which looks like this:
public class SquaredImageView extends ImageView {
public SquaredImageView(Context context) {
super(context);
}
public SquaredImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquaredImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
}
The CardView layout looks like this:
<CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:background="#color/snow"
android:clickable="true"
android:orientation="vertical">
<!-- Image -->
<com.test.views.SquaredImageView
android:id="#+id/card_image"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Content -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="32dp"
android:orientation="horizontal">
<!-- Title -->
<TextView
android:id="#+id/card_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:singleLine="true"
android:textColor="#color/stone_dark"
android:textSize="14sp" />
<!-- Button -->
<ImageView
android:id="#+id/card_menu"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:clickable="true"
android:scaleType="center"
android:src="#drawable/ic_menu" />
</LinearLayout>
</CardView>
It means, that RecyclerView's adapter don't know the dimensions of CardView in advance.
As you probably know, RecyclerView has no system, which can measure its child-views, to make wrap its content correctly.
But unpredictable SquareImageView + fullscreen RecyclerView works fine in most of cases except the one described in this question.
So what's the problem? You should use your own LayoutManager or WrappableLayoutManager by #se-solovyev to solve your problem.
The problem is in unpredictable SquareImageView. When LayoutManager tries to measure its child, it gets nothing. It means that RecyclerView displayed in fullscreen (as if height and width are set to match_parent).
So the question is: how to make RecyclerView with unpredictable SquareImageViews wrap its content correctly?

Non Scroll RecyclerView scrolling issue in Android SDK 23

I am implementing a RecyclerView inside a ScrollView. In order to have only one scrolling behaviour on the entire page I implement a NonScrollRecyclerView version. The implementation is as follows:
public class NonScrollRecyclerView extends RecyclerView {
public NonScrollRecyclerView(Context context) { super(context); }
public NonScrollRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev){
if(ev.getAction() == MotionEvent.ACTION_MOVE)
return true;
return super.dispatchTouchEvent(ev);
}
}
Once i update my build and target settings to SDK 23, I have trouble scrolling the page which contains the NonScrollRecyclerView. The specific problem is that the page scrolls OK until i reach the recycler view portion and once i scroll onto this view I am unable to scroll anymore, either up or down.
I DONOT face this problem with SDK 22 and below
My xml is as follows:
XML #layout/rv contains the recycler view
<ScrollView 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:background="#color/background_gray">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background_gray"
android:orientation="vertical">
<include
layout="#layout/row_mall_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv_mall_header"
android:layout_marginTop="8dp"/>
<include
layout="#layout/row_mall_shops"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv_mall_shops"
android:layout_marginTop="8dp"/>
<include
layout="#layout/row_mall_coupons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv_mall_coupons"
android:layout_marginTop="8dp"/>
<include
layout="#layout/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv_mall_feeds"
android:layout_marginTop="8dp"/>
</LinearLayout>
</ScrollView>
XML - #layout/rv
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_gray"
android:id="#+id/ll_mall_feeds">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:paddingTop="6dp"
android:paddingBottom="6dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_feedcount"
android:textColor="#color/semi_theme_blue"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="12dp"
android:layout_centerVertical="true" />
</RelativeLayout>
<com.project.ui.NonScrollRecyclerView
android:id="#+id/nrv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:listSelector="#android:color/transparent" />
</LinearLayout>
RecyclerView and ListView are not recommended inside a ScrollView because elements hights are not calculated when rendering the ScrollView. This means, your adapter might not be populated when the ScrollView is shown and later when the RecyclerView is notified about data changes (for instance when you initialize your adapter), there's not way to recalculate the elements heights.
It's really a pain in the neck because you have to try to calculate the elements heights and it's never accurate, so you will have discrepancies when showing a ListView or a RecyclerView inside a ScrollView. Some examples of how to calculate the elements heights can be checked here and here.
My advice is to turn your RecyclerView into a LinearLayout and add elements programmatically, so you emulates the ListView or RecyclerView behaviour:
LinearLayout layout = (LinearLayout) rootView.findViewById(R.id.files);
layout.removeAllViews();
for (int i = 0; i < fileAdapter.getCount(); i++) {
final View item = fileAdapter.getView(i, null, null);
item.setClickable(true);
item.setId(i);
item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fileContentRowPosition = v.getId();
# Your click action here
}
});
layout.addView(item);
}
Here its the XML with the files definition:
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<LinearLayout
android:id="#+id/files"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
The whole java code can be checked here and the whole Layout here.
On the other hand, if you still want to continue with your implementation, and regarding your issue, you can check this article about Handling Scrollable Controls in Scrollview
Best regards,
For only one scrolling in the entire page you can use NestedScrollView instead of ScrollView and set recyclerView.setNestedScrollingEnabled(false);

make page scroll disable in pagerslidingtabstrip

Can we disable page sliding in PagerSlidingTabStrip ? I am using PagerSlidingTabStrip where tabs are created dynamically in my example. On each fragment there are tow buttons
Chapter wise analysis
Rank wise analysis
What i want is when user click on Rank wise analysis Sliding should disable and tabs get hide and when click on Chapter wise analysis tabs should visible again and sliding should also enable. How to achieve this? Tabs hide and show is working properly but am not able to make slide disable.
Create a separate class which should extend ViewPager:
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
}
And then use this viewPager to set in your xml file like this:
<com.packagename.CustomViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Then in your activity, set your FragmentPagerAdapter to this viewPager:
mViewPager.setAdapter(YourFragmentPagerAdapter)
Extend ViewPager and override onInterceptTouchEvent() and onTouchEvent().
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return false;
}
Here is my solution....
I make slight changes with my layout.Previously i had 2 buttons on each fragment.
Now i place that two button in parent activity.. here is my xml file.
<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" >
<LinearLayout
android:id="#+id/lintab"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.joyoflearning.utils.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip"
android:background="#drawable/background_tab" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/lintab"
android:background="#drawable/background_tab"
tools:context=".TestAnalysisActivity" />
<LinearLayout
android:id="#+id/RankAnalysisFragment"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/linButtons"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="#+id/linButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/darkGray"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp" >
<Button
android:id="#+id/btnChapterWise"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:background="#drawable/btn_blue_bg"
android:drawableLeft="#drawable/checkbtn_icon"
android:drawablePadding="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="Chapterwise"
android:textColor="#ffffff" />
<Button
android:id="#+id/btnRankWise"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:background="#drawable/btn_blue_bg"
android:drawableLeft="#drawable/uncheckbtn_icon"
android:drawablePadding="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="Rankwise"
android:textColor="#ffffff" />
</LinearLayout>
Now click on ChapterWiseAnalysisbutton will hide LinerLayout having id RankAnalysisFragment and click on RankWiseAnalysis will hide Tabs,ViewPager and add a fragment to LinerLayout .

Categories

Resources