android ViewPager customizable - android

I need to implement a scroll view as shown:
That is, in "idle" state image "1" is visible in full size and image "2" is visible partially (thus giving a clue to the user that he can scroll the content). After scrolling scrool view must not stay in intermediate state and scrolling must be completed (like iOS's Scroll View does when "Paging Enabled" is turned on):
I refused to use HorizontalScrollView, because it has nothing similar to "Paging Enabled" property.
After googling, I came across android.support.v4.view.ViewPager. It's scrolling behavior is perfectly what I want, but I have no good idea how to support "partially visible" next image in ViewPager? Technically, what should I return in the
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)?
For the present, my code is
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.stage_select_image_layout, container, false);
ImageView imageView = (ImageView) view.findViewById(R.id.stage_select_image_layout_image);
imageView.setImageResource(m_imageResourceId);
return view;
}
But it results in "exactly one image per page" behavior, not what I want (see the very first figure).

This does the trick:
ViewPager pager = ...;
pager.setOffscreenPageLimit(2);
pager.setPageMargin(-200);

The easiest thing to do is, is in your PagerAdapter, implement an override for getPageWidth. The return value is a percent that the view takes up of the total space.
#Override
public float getPageWidth(int position) {
return 0.75f;
}

Use the widthFactor attribute of the ViewPager's LayoutParams. It should scale it so you can see a little of the next page.

Related

View is in the last position of parent, but still being blocked

What I want to do
In a BottomSheetDialogFragment, I want to inflate a view that always stick at the bottom of the screen, no matter what state (collapsed / expanded) the BottomSheetBehavior is in.
What I have done
In a subclass of BottomSheetDialogFragment, I inflate a view from XML and add it as a child of CoordinatorLayout (which is BottomSheetDialogFragment's parent's parent):
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setupBottomBar(getView());
}
private void setupBottomBar (View rootView) {
CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
parentView.addView(LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false), -1);
}
The code runs without error.
And when I use Layout Inspector to look at the View hierarchy, the view structure is also correct:
You can also download the layout inspector result here, and open it using your own Android Studio.
The problem
However, even though it is inserted as the last child of the CoordinatorLayout, it is still being blocked by the BottomSheetDialogFragment.
When I slowly scroll the BottomSheetDialogFragemnt downwards (from collapsed state to hidden state), I can finally see the view that I want to inflate behind the fragment.
Why is this happening?
The answer
As #GoodDev pointed out correctly, it is because the root view (design_bottom_sheet) has been set a Z translation by BottomSheetDialog.
This provides an important information that - not only sequence in a View hierarchy will determine its visibility, but also its Z translation.
The best way is to get the Z value of design_bottom_sheet and set it to the bottom bar layout.
private void setupBottomBar (View rootView) {
CoordinatorLayout parentView = (CoordinatorLayout) (rootView.getParent().getParent());
View barView = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
ViewCompat.setTranslationZ(barView, ViewCompat.getZ((View)rootView.getParent()));
parentView.addView(barView, -1);
}
EDIT 2
Ok, now I see your requirement, try this one:
private void setupBottomBar (View rootView) {
CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
View view = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
// using TranslationZ to put the view on top of bottom sheet layout
view.setTranslationZ(100);
parentView.addView(view, -1);
}
EDIT:
OK, I check your layout and check the BottomSheetDialogFragment source code, found the reason:
In BottomSheetDialogFragment using BottomSheetDialog dialog, the method setContentView in BottomSheetDialog using wrapInBottomSheet to put the content view in R.id.design_bottom_sheet layout. So you need override the BottomSheetDialogFragment's public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) to fix your problem.
Or, change your setupBottomBar method to:
private void setupBottomBar (View rootView) {
FrameLayout frame = (FrameLayout)rootView.getParent();
frame.addView(LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, frame, false), -1);
}
and in your item_selection_bar layout file, change height and layout_gravity:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content">
BottomSheetDialogFragment doc says: Modal bottom sheet. This is a version of DialogFragment that shows a bottom sheet using BottomSheetDialog instead of a floating dialog.
So the BottomSheetDialogFragment is a Dialog, Dialog is a floating view, so will cover the Activity content when BottomSheetDialogFragment is showing.
#goodev has give a nice answer.
Your problem
View's Z position causes this problem. Although the TextView is the last position you still can not see it.
How to solve
You can set design_sheet_bottom's Z to TextView.
private void setupBottomBar (View rootView) {
CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
View view = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
view.setZ(((View)rootView.getParent()).getZ());
parentView.addView(view, -1);
}
And I think above way is very boring, can you put your two view RecyclerView and TextView into a layout ? Then you can inflate theme together in onCreateView() method.

How to set/change value while onCreate under TabLayout first Tab

i have try a lot of example or tutorial on tablayout, all work fine
(https://www.simplifiedcoding.net/android-tablayout-example-using-viewpager-fragments/, http://www.androidbegin.com/tutorial/implementing-fragment-tabs-in-android/)
but now i encounter 1 problem, which is i dont know how to set/change the TextView/ImageView while onCreate/onLoad
so far, what i able to do is, write all my code under onTabSelected, but this is not my solution because i cant show empty or static values on the 1st tab, then have to wait until click or slide again then only load the real data.
i'm sure it have a way or solution for my problem, can anyone share it to me (code/website)
or in order to have this Tab feature with viewpager contain recyclerview, Tablayout is not the right way to code, perhaps it have another more correct way to code.
Do these changes inside of onCreateView of fragment that you want
Example:
//Our class extending fragment
public class Tab1 extends Fragment {
//Overriden method onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Change R.layout.tab1 in you classes
View view = inflater.inflate(R.layout.tab1, container, false);
TextView textView = (TextView) view.findViewById(R.id.you_textview_id);
textView .setText("Your text to show");
//Returning the layout file after inflating
return view;
}
}
The TextView need to be previous declared in tab.xml that you're inflating, in our example, tab1.

Which way should I choose to inflate view in ViewPager's instantiateItem method?

I write a Android application using ViewPager. And now, I have a confusion when use ViewPager.
When I use the code below to inflate a view from a layout xml file and add it into viewpager.
public Object instantiateItem(ViewGroup container, int position) {
View view = View.inflate(ShareTasksActivity.this, R.layout.item_internal_advertisement, null);
container.addView(view);
return view;
}
But When I use code below, the viewpager will show nothing.
public Object instantiateItem(ViewGroup container, int position) {
View view = View.inflate(ShareTasksActivity.this, R.layout.item_internal_advertisement, container);
return view;
}
I think the two snippets do the same thing, but the results are different. I don't know why. Can anyone help me ? Thank you !
Actually, these snippets are doing slightly different things:
Inflates view and add it to the container;
Just inflates view;
The issue here is the following:
call to View.inflate(ShareTasksActivity.this, R.layout.item_internal_advertisement, container); is equal to the following one: LayoutInflater.from(ShareTasksActivity.this).inflate(R.layout.item_internal_advertisement, container, false); (checkout its source). The same time instantiateItem() documentation mentions:
The adapter is responsible for adding the view to the container given
here
So, second variant doesn't work at all because it is not adding view to the container.
However, first variant per mine understanding also has an issue: layout parameters You might provide for top level view R.layout.item_internal_advertisement will not be applied if You provide null parent view.

View with 2 ListViews and headers moves the other listview

In my view I have 2 listviews, both have a header. When I scroll one list the other listview moves too (not a lot) but it moves enough where the header is no longer visible.
If I remove the headers this does not happen though.
in my xml I set android:splitMotionEvents="true" but that didn't do anything
this is how I set my header in my listviews
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle saved){
View v = inflater.inflate(R.layout.sin_preplan_layout,container,false);
sinList = (ListView)v.findViewById(R.id.sin_listView);
prePlanList = (ListView)v.findViewById(R.id.preplan_listView);
sinList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
prePlanList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
View v2 = inflater.inflate(R.layout.sin_preplan_header,(ViewGroup) v.findViewById(R.id.header_layout_root));
prePlanList.setHeaderDividersEnabled(true);
prePlanList.addHeaderView(v2);
sinList.addHeaderView(v2);
return v;
}
any ideas as to why this happens?
You are adding the same instance twice to different views, which is discouraged. Try this:
View firstHeader = inflater.inflate(R.layout.sin_preplan_header,(ViewGroup) v.findViewById(R.id.header_layout_root));
prePlanList.addHeaderView(firstHeader);
View secondHeader = inflater.inflate(R.layout.sin_preplan_header,(ViewGroup) v.findViewById(R.id.header_layout_root));
sinList.addHeaderView(secondHeader);

Cannot getHeight of TextView when Fragment onCreateView

I have a Fragment which contain a TextView call as mTextView. I want to get height of mTextView after append content to it in onCreateView of Fragment like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(
R.layout.myfragment, container, false);
mTextView = (TextView) view.findViewById(R.id.myTextView);
int mHeight=mTextView.getHeight();
}
but it's always return 0 value.
Do you try to get it after
setContentView(R.layout.your_layout);
right?
If you try to get the height just after onCreate, you won't be able to get because still the window is not focused. Try like this :
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// your code here
int mHeight=mTextView.getHeight();
}
The reason the View's dimentions are 0 is because when you are querying them, the view still haven't performed the layout and measure steps. You only told the view how it would "behave" in the layout, but it still didn't calculated where to put each view.
There are a few tricks to get that size though. You can use this question as a starting point although I don't like the accepted answer's approach very much.
How to get the width and height of an android.widget.ImageView?

Categories

Resources