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);
Related
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.
Inside the dialogFragment I have viewPager with two pages. Every page contains a custom adapter. One adapter with list of spinners, other adapter with list of EditTexts. ViewPager adds adapters fine.
public class PageFragment extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pagefragment_newprod, null);
LinearLayout ll=(LinearLayout) view.findViewById(R.id.tvLL);
ListView listView=new ListView(getActivity());
ll.addView(listView);
if (pageNumber==0){
dropDownAdapter=new DropDownAdapter(getActivity(), fillListAdapter);
listView.setAdapter(dropDownAdapter);
} else if (pageNumber==1){
boxAdapter = new BoxAdapter(getActivity(), filledFields);
listView.setAdapter(boxAdapter);
}
return view;
}
}
But it works to slow! Current Adapter (I mean at the curren page) create views every milisecond! Look at this:
public class BoxAdapter extends BaseAdapter{
...
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (view == null) {
view = lInflater.inflate(R.layout.addproduct_item, parent, false);
}
Log.d(LOG_TAG, "====As I said every milisecond...======");
EditText editText = (EditText) view.findViewById(R.id.addProductEditText);
editText.setText(p.value);
return view;
}
}
Even when I focused the EditText this Log.d write messages every milisecond!
Besides that, adapter at the next page works too. I have other Log.d at the other adapter getView and it works when I used different page's adapter!
Please help me to understand what is wrong...(
The question has already been solved in the comments. The solution for the OP was apparently to remove complex fragments and their adapter. However, I also had complex fragments in a tab layout with a ViewPager, and the following solution fixed the slow paging problem:
viewPager.setOffscreenPageLimit(2);
The 2 will keep two pages away from the current page in memory. This was enough for me because I had three tabs. Be careful about keeping too many pages in memory, though. See the documentation.
I have a ViewGroup in top of Activity, 3 buttons and 3 ListView ( they are placed horizontally ). When I scroll ListView from down to up, my buttons and ViewGroup should be scrolled accordingly, from down to up.
My question - how can I implement it? ( scrolling ViewGroup and buttons )
Updated: buttons scrolls ListViews left to right and right to left ( like tab bar ), but ViewGroup and button doesn't moves;
ListView has very convenient method addHeaderView. So put your ViewGroup and buttons into separate xml layout. Inflate view from this xml and add it to your ListView using addHeaderView.
From the top of my head:
1)Make a list adapter for the list view. This class must extend SimpleAdapter, BaseAdapter, etc.
2)Make a XML layout for the list`s item, that includes the buttons and other elements you may desire. (your_item_layout.xml). This layout implements a listview if you want.
3)The list adapter needs an data structure to storage information for the list view, like an ArrayList, Map, Array, etc.
For example: private ArrayList al;
4)This list adapter function
public View getView(int position, View v, ViewGroup vg){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.your_item_layout,null);
/*set as you wish the elements of the item layout*/
Button b1 = v.findViewById(R.id.button1_item_layout);
b1.setText("OPEN FILE " + al.get(position));
b1.setOnClickListener(new OnClickListener(){
public void onClick(View v){
/*do something*/
}
});
}
I hope that helps!
I am new in programming to android now my work is paused as I am not getting how to accomplish the following I want to create a view which will have paging capability and in the view there would be textview to display the name of person and a list of name of all his relatives .... And the list can be long so it should be scrollable... I know to do paging and list independently but do not know how to combine the both in one view.... I hope I am clear with my question... So guys help me how to accomplish this...
I know to do paging and list independently but do not know how to combine the both in one view
So you can create xml like this :
Linear Layout/ Relative layout
Text View
List View
Put this XML in fragment
EDIT :
public class Fragment1test extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
//This layout contains your list view
View view = inflater.inflate(R.layout.your_view_xml, container, false);
//now you must initialize your list view
Listview listview =(Listview)view.findViewById(R.id.your_listview);
//Here items must be a List<Items> according to your class instead of String[] array
ListAdapter listadapter = new ListAdapter(getActivity(), android.R.layout.simple_list_item_1, items)
ListView.setAdapter( listAdapter());
//getActivty is used instead of Context
return view;
}
}
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.