How do I properly add multiple fragments to a fragment transition? - layout

I recently asked a question about fragments here:
After a lot of messing around I found what the problem was, but after more fooling around, and research (in which correct code seemed identical to mine), i cant figure out what my problem is.
After everything is created, I find that only the last fragment added to the transaction is visible. This is my code to add them:
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
UrlListFragment urlfragment = new UrlListFragment();
MyWebFragment webfragment = new MyWebFragment();
trans.add(R.id.fragment_container, urlfragment, "my_url_fragment");
trans.add(R.id.fragment_container, webfragment, "my_web_fragment");
trans.commit();
And this is my main xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
What am I doing wrong, or what can be done so both fragments are added correctly and can be seen correctly?

Unfortunately you cant use fragments in this way you need to use just one fragment per container. It will amount to the same visual layout anyway.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/fragment_container1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<FrameLayout
android:id="#+id/fragment_container2"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
and
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
UrlListFragment urlfragment = new UrlListFragment();
MyWebFragment webfragment = new MyWebFragment();
trans.add(R.id.fragment_container1, urlfragment, "my_url_fragment");
trans.add(R.id.fragment_container2, webfragment, "my_web_fragment");
trans.commit();

To add multiple fragments inside one layout, you need to call add() and commit() methods for each individual fragment. But if you're adding your fragments in a loop, or for example like below:
FragmentManager manager = getFragmentManager();
manager.beginTransaction().add(R.id.parentView, myFragment1, "fragment:1").commit();
manager.beginTransaction().add(R.id.parentView, myFragment2, "fragment:2").commit();
This might also get you into some problems. Since, the commit() method doesn't add the fragment immediately, you need to make sure that the previous fragment was attached from activity's onAttachFragment() method and then move further adding another fragment.

Related

How to declare and find a layout programmatically without using findViewById

I have a layout and i am assigning an id to the layout then i find the view of the layout using id. is there a way a can find the layout directly and programmatically like using getBackground
My XML file
<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"
tools:context=".fragments.RegisterFragment"
android:orientation="vertical"
android:background="#drawable/gradient_animation"
android:gravity="center_horizontal|center_vertical"
android:id="#+id/linear_layout">
<EditText
android:id="#+id/et_first_name"
android:hint="Enter first name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"/>
</LinearLayout>
Declaring the layout and finding its view by id in activity
LinearLayout linearLayout = findViewById(R.id.linear_layout);
Declaring the layout and finding its view by id in fragment
LinearLayout linearLayout = view.findViewById(R.id.linear_layout);
Is the there a way i can directly get the layout background without using findViewById

How to add constrainlayout only to floating actio button?

I want to add constrainlayout only two the last two floating action button with nested framelayout. any help would be highly appreciated. My main idea is to able to move and position the floating action button from graphical user interface.
I have notice that android gravity help to put button at right and the center from right with
android:layout_gravity="right|center"
how can i add a button at right but between center and end at bottom.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000"
tools:context=".MediaPresentationActivity"
android:id="#+id/FrameLayout">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/videoViewPresentation"
android:layout_gravity="center" />
<ImageView
android:id="#+id/imageViewPresentation"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="left|top"
android:background="#ffffff"
android:src="#drawable/serv24logobig" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</LinearLayout>
//*how to add only below two floating action button as constrainlayout //
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="right|center"
android:src="#android:drawable/stat_sys_phone_call"
android:visibility="visible"
app:backgroundTint="#android:color/holo_red_dark"
app:elevation="12dp"
app:rippleColor="?android:attr/colorActivatedHighlight" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="right|center"
android:src="#android:drawable/stat_sys_phone_call"
android:visibility="visible"
app:backgroundTint="?android:attr/colorMultiSelectHighlight"
app:elevation="12dp"
app:rippleColor="?android:attr/colorActivatedHighlight" />
</FrameLayout>
FrameLayouts only allow ONE child (well they allow N children, but they overlap, because it doesn't support children positioning, rather it expects them to take all the available space), so if you want to use a ConstraintLayout to position two items inside a FrameLayout, then you need to ensure that the children of your FrameLayout, is a ViewGroup that allows positioning of its own children.
Let's see what you got.
Your Root is a FrameLayout, perhaps you should consider making it a ConstraintLayout to begin with...
You're asking your Root layout to wrap its contents. Unless this is a custom view, this is somewhat frowning, but not wrong; since I don't know how you're using this, it's hard to tell if this is the correct approach in this case.
I don't know how your UI should look, but from what I see, you have a series of nested LinearLayouts, Vertical, then Horizontal to have an ImageView and a VideoView... not sure how you expect these to be positioned.
Down Below you have an empty LinearLayout... (?)
and then you tossed the two FABs.
This is not going to work. I suggest you revisit your entire Layout (which, btw, is incorrect as pasted, because you're closing the FrameLayout twice...).
If you post an image of what your desired output is, perhaps we can help you better understand where your problem is. As it is, it's not possible to determine.
The answer to your question, as written at this time is:
"How can I add a constraint Layout onlo to the last two FABs?"
You can't (for the purposes I think you want), but if you really want to see why, and what would happen:
Simply add, inside your FrameLayout this:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<!-- YOUR FABS GO HERE -->
</androidx.constraintlayout.widget.ConstraintLayout>
This will obviously NOT LOOK THE WAY YOU WANT, but that's why I asked you in the comment above, "show us what you want, we need a minimal reproducible example of what you need".
There was a reason why I asked that, not to annoy you, but to help you. You chose to ignore it, and that's as far as I can go to help you with the information I have.

Android clickable layouts above empty views

My project also uses Xamarin with MvvmCross, but I don't think this will effect the answer since the problem is all view-layout/axml related.
I have a GridView that summarizes a list of contacts. When clicking on this grid view, I would like the user to be taken to another screen to add more contacts to this list (so there is more space).
Subscribing to the GridView's OnClick event gives me an exception, saying I should be subscribing to the item click event, so I have done this using a clickable relative layout that surrounds the GridView (and its accompanying empty image view) as such:
...
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/addContactsRelativeLayout"
android:clickable="true">
<ImageView
android:id="#+id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/ic_add" />
<Mvx.MvxGridView
android:id="#+id/addContactsGridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:MvxBind="ItemsSource Contacts"
local:MvxItemTemplate="#layout/contact_summary_item"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:columnWidth="55dip"
android:gravity="center" />
</RelativeLayout>
...
This works fine when the GridView is empty, and the empty ImageView is shown. However, when there are items in the GridView, the RelativeLayout no longer seems to exist and clicks over the GridView can be seen to highlight items on the GridView. This means the user is not taken to the screen to edit their contact list.
I have tried several different configurations and attributes from similar questions on SO, but I think the addition of an empty view is causing problems. Any help would be greatly appreciated.
Ok, after a lot more playing around I found a solution.
Essentially it's adding another relative layout, higher in the z-index and therefore above the 'real' contents, within the surrounding relative layout.
...
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<ImageView
android:id="#+id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/ic_add" />
<Mvx.MvxGridView
android:id="#+id/addContactsGridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:MvxBind="ItemsSource Contacts"
local:MvxItemTemplate="#layout/contact_summary_item"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:columnWidth="55dip"
android:gravity="center"
android:focusable="false"/>
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clickable="true"
android:id="#+id/addContactsRelativeLayout"/>
...
Then just move all your click listeners to listen to the relative layout at the bottom.

Define list view with static elements on android in xml?

I want to create fragment which would display static menu as a set of rows in a list.
I like iOS method with static cells in a tableview. How can I achieve this in android (so no code is needed to define elements, just xml)
Is there any regular way to define static elements in xml next way
(pseudo-code)
list_view.xml
<List view>
- use element my_row with onclick=row1_clicked and title="row 1"
- use element my_row with onclick=row2_clicked and title="row 2"
- use element my_row with onclick=row3_clicked and title="row 3"
- use element my_row with onclick=row4_clicked and title="row 4"
</List view>
my_row.xml
<My Row>
- text field (title should go here)
- on click (on click should go here)
</My Row>
So basically I want to "include" row in list and do it on xml level (without code).
Unfortunately, list view definition via xml is forbidden. Mess with adapters is required instead.
Some progress can be made using a string-array, e.g.,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/sports_array"/>
</LinearLayout>
couple with
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="sports_array">
<item>Shuttle Badminton</item>
<item>Tennis</item>
<item>FootBall</item>
</string-array>
</resources>
source: http://theopentutorials.com/tutorials/android/listview/android-creating-and-populating-listview-items-in-xml/
You can use a vertical LinearLayout nested within a ScrollView to get what you're looking for. Put your "listview" items inside the LinearLayout, and style them to look like elements of a listview.
If you absolutely must use a ListView (e.g. you're using ListFragment), you'll have to use a ListAdapter subclass or roll your own.
Actually there is a way!
Re-using Layouts with include - Tag
Simply define a Layout you want to reuse.
<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="horizontal">
<ImageView
android:id="#+id/profileImage"
android:layout_width="128dp"
android:layout_height="128dp"
android:src="#drawable/lena" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/profileOnline"/>
</LinearLayout>
Then include it in your ViewGroup as many times as required
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<include layout="#layout/titlebar"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
android:padding="10dp" />
...
</LinearLayout>
You can also override all the layout parameters (any android:layout_* attributes) of the included layout's root view by specifying them in the tag. For example:
<include android:id="#+id/news_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/title"/>
More information at http://developer.android.com/training/improving-layouts/reusing-layouts.html

`VideoView.start()` cause other views to break

When my activity receives a new intent via onNewIntent, it updates the data of three Views, an ImageView, a TextView, and a VideoView. The problem is, the two other views just flash, then disappear when my VideoView comes on. After scattering a few breakpoints, I discovered that they appear when their content is set, but disappear when VideoView.onStart() is called in my MediaPlayer.onPrepared() method. I also have an AlertDialog show up when the menu button is pressed. After pressing the menu button, it shows up. I'm on Android API 9, as this is the API on the device I'm working on. I really need help, so I'd appreciate any advice.
Here's the layout. I don't think it's the issue though:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:keepScreenOn="true" >
<TextView
android:id="#+id/marquee"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:ellipsize="marquee"
android:focusable="false"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#android:color/white" >
</TextView>
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_above="#id/marquee"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical" />
<VideoView
android:id="#+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/marquee"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_toLeftOf="#+id/image" />
</RelativeLayout>
Take note that the TextView is meant to be a marquee; it's supposed to keep scrolling sideways, until it is disposed of. I discovered that when the text is too short for it to start the marquee, the TextView AND the ImageView disappear (as stated earlier, they appear for a split second, then disappear). However, when the text causes the marquee feature to activate, everything works.
CURRENTLY:
I got it to work by calling postInvalidateDelayed(500) on my ImageView and TextView after calling VideoView.start(). I think the start() method is causing the problem, and requires that other views call invalidate(). Also, for some reason, there needs to be a small delay in-between the call to start() and the call to invalidate().
The layout is the issue.
Your VideoView is declared as match_parent, match_parent, allowing it to consume the whole width and height of the screen. Since you declared it last on the xml file (You used RelativeLayout. Ordering matters), the TextView and the ImageView would be covered by the VideoView.
If you're confused,
match_parent is basically the same as fill_parent. It's just another name for fill_parent in android 2.3+
Now what can you do about it?
Reorder your views in such a way that the largest is declared first. In this case, VideoView, then ImageView, then TextView.
Also note that your ImageView has height set to fill_parent - you may not want that.
I created a method, but it seems very bad:
private void startVideo() {
this.videoView.start();
if (this.imageView != null)
this.imageView.postInvalidateDelay(500);
if (this.textView != null)
this.textView.postInvalidateDelay(500);
}
It works, but it makes me feel dirty.

Resources