Complex Android UI design guidance needed (fragments)
Asked Answered
A

2

11

I am developing an applications that is aimed at Tablets and Google TVs. It will be like many standard Google TV applications with a LeftNavBar and a top Search bar that is common to all application screens. It will look something like the following image:

Main Screen enter image description here

The RED area will be different for all other screens. It may contain data like following screens mockups:

Activity One loaded into main container enter image description here

Activity Two loaded into main container enter image description here

So you can see that completely different sections can be loaded in the main area.

Screen 3 can be loaded as a detailed section when selecting any list item in Screen 2 (say in fragment list) OR it can be loaded as a result of selecting a tab (which will appear in LeftNavBar).

Here is how I am trying to implement it.

Step 1. I Created a main Activity with the following XML:

<?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"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#9ccc" >

        <!-- Top Bar -->

    </LinearLayout>

    <FrameLayout
        android:id="@+id/mainContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <!-- main Red Container that will load other Activities -->

    </FrameLayout>
</LinearLayout>

mainContainer is the RED container where I want to load the Activities. LeftNavBar will be added to this Activity as its the parent of All.

Step 2 I created ActivityOne & ActivityTwo with two & three Fragments in them respectively (as shown in above second & third image).

*Step 3 I am trying to load the ActivityOne in main page's mainContainer FrameLayout... But I cannot add it.

I tried by adding the ActivityOne to mainContainer as follows:

View v = (new ActivityOne()).getWindow().getDecorView();
FrameLayout mainContainer = (FrameLayout) findViewById(R.id.mainContainer);
mainContainer.addView(v);

but the getWindow() returns null....

Other issue occurs because all the data comes from a remote services .. so please also suggest how would I be able to hold references to all the loaded Activities in mainContainer in a some kind of stack ... so I can just reload the already loaded activity instead of creating its new instance.. This will be used on BACK button press.

OR

Instead of loading an activity into the above RED container, I should create two Activities each with their own Fragments & a LeftNavBar. This might be easier than the aforementioned approach. or this might be the only solution.... however I feel that saving state for BACK buttons might get messy .. but I will try implementing this

What would you do if you had to create this type of application? How would you design the UI layout for best performance/practice?

Your suggestions in helping me setting this app's layout are much appreciated.

Auscultation answered 25/7, 2012 at 7:26 Comment(2)
could you zip you code, upload it somewhere and send a link? You can never instantiate an Activity, framework does that. I don't know if ActivityOne is actually a Activity in your code. Go through Panoramio for Google TV sample app. It does what you intend to do here.Dittography
Thanks for the reply. I looked at the Panoramio sample app. It has TWO activities in it and they include the LeftNavBar in onCreate() event of the activity. I will do so If this is the correct way to just include the LeftNavBar in all activities. I was trying to find an alternative way because I will have many activities (7 - 10) in my app. thats y i was trying above approach .. to have a parent activity with LeftNavBar and load the Other activities/fragments in some main container.Auscultation
C
3

Disclaimer

This is where fragments can get tricky. The problem would be simple if Activity 1 & 2 had identical layouts so that you could simply attach/detach fragments and use the fragment back stack to unwind.

Because you want 2 unique layouts to house your fragments, things are going to be a little more involved. If at all possible I would try to use the same layout so that you can take the easy path.

As another option, you could use two activities as you outline above and send data back and forth with Intents.

That said, if I really had to implement this solution as written, here is what I would do. Note that I am not advocating this solution but myself do not know of a better way of doing things.

The Solution

Create a FragmentActivity whose view would be Main Screen as you've defined above. The layout for the Main Screen would contain:

  • Left nav bar
  • Top bar
  • 2 layouts. layout1 and layout2. These would be contained in a parent layout i.e. RelativeLayout or LinearLayout and would contain the necessary FrameLayout elements for your fragments.

Example using your XML (note, tags are a bit brief):

<?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"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#9ccc" >

        <!-- Top Bar -->

    </LinearLayout>

    <LinearLayout android:id="@+id/layout1">
        <FrameLayout android:id="@+id/listFragment" />
        <FrameLayout android:id="@+id/contentFragment" />
    </LinearLayout>

    <LinearLayout android:id="@+id/layout2">
        <FrameLayout android:id="@+id/imageFragment" />
        <FrameLayout android:id="@+id/boxFragment1" />
        <FrameLayout android:id="@+id/boxFragment2" />
        <FrameLayout android:id="@+id/boxFragment3" />
    </LinearLayout>

</LinearLayout>

The main idea is that you then show/hide layout1 & layout2 i.e. set android:visibility="gone" based on the state of your app.

The disadvantages of this method are:

  • Using fragment backstack may be impossible, instead you'll have to track where the user is in your UI flow and manage the back button to show/hide layout
  • You may need to take special care to attach/detach fragments when you show/hide their parent view to reduce resource consumption while the fragments are invisible

The advantages are:

  • Easy communication between fragments and the base activity since only 1 activity is used
Castaway answered 1/8, 2012 at 23:33 Comment(3)
Thanks... this might be a possibility if I had two Activities to load in that mainContainer .. But I have many activities (7 - 10 or more) each with its unique layout .. So this solution is not applicable. I have decided to load all the activities separately with their sub-fragemtns .. all these activities will derive from baseActivity which will insert the LeftNavBar into that activity ...this seems easier and manageableAuscultation
plus ... I have not marked ur comment as answer but have awarded you the bounty .. because you are the only person who bothered to think and reply in detail ... so thank you againAuscultation
Yes, your solution seems easier to manage with that number of activities.Castaway
P
-1

Re: The nested Fragments problem

To get around the 'nested Fragments' problem in our application where (as you correctly note) Fragments cannot add Fragments I hosted a single templating Fragment under the activity whose only purpose was to define a set of place holders for other fragments to anchor to. When adding further Fragments to the activity past this point I used the templating Fragment's view place holder +@ids to identify the "root" or parent view Id for the Fragment being added.

    getSupportFragmentManager().beginTransaction().add(#someIdFromTheTemplateFrag, fragment, fragmentTag).commit();

The Fragment I was adding then knew where to anchor itself in the current layout and of course then went about it's merry way of add it's view. This had the effect of attaching a Fragment to another Fragment hence achieving the desired visual 'nesting'...

Pageantry answered 25/7, 2012 at 13:56 Comment(7)
Not only did that not answer his question you are promoting the incorrect usage of fragments, nesting fragments can result in subtle lifecycle bugs and is not promised to work in future releases. He can easily create the desired effect using simple layouts that will hold his fragments together, no nesting required. Ref: #6222263Phenylalanine
There is no hierarchical nesting with what is described here. The activity still owns all the Fragments directly. This approach allows you to flow views controlled by modular, reusable fragments- there will be no subtle bugs since the activity still owns the fragments directly, it can destroy, recreate and attach at will but the positioning of the fragments can be controlled by this 'controller' fragment.Pageantry
"I hosted a single templating Fragment under the activity whose only purpose was to define a set of place holders for other fragments to anchor to." - Sounds like placing a fragment within a fragment to mePhenylalanine
The issue you linked to is about adding a Fragment to a Fragment in code (or at least that's how I read it) thus blurring the boundary between who has control over the Fragment- this is about "putting that XML there" in the view layer. I'd like to continue this chat if you feel this is wrong? Chatroom?Pageantry
chat.stackoverflow.com/rooms/14407/…Phenylalanine
HandlerExploit has pointed out this behaviour is unsupported and offered an alternative in our chat above. Every day is a learning day!Pageantry
What do u propose to me??? Im my case, should I use two Activities, each merging the LeftNavBar and each with its own Fragments?? So, as per my provided images, Activity2 will have two fragments and Activity3 will have three?? Would you prefer this approach?....This is a big project and it has many screens (not two as I have shown) and I dont want to regret anything ....ur help is greately appreciatedAuscultation

© 2022 - 2024 — McMap. All rights reserved.