I'm going to create a complex/normal design that has an empty screen layout & shimmer layout.
my question is to have all in one layout with multiple <include> files is better than doing two fragments and keep replacing them.
more details:
1- make the data screen shown & empty screen hidden as follows:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar"
layout="#layout/common_toolbar" />
<include layout="#layout/empty_layout"/>
// my data layout
</LinearLayout>
2- create a FrameLayout and keep change the container for different screens with multiple fragments:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
I need to know the best practice as depending on slow rendering of multiple views.
another question, is that included in for shown/hidden views or it depends on shown ones only as I got confused
and need to apply best practices.
if you attend to reuse some views Fragment is the best, otherwise, if you looking best to render I advise you to use constraint layout and section your views with a group so you can hide and show group
take a look to this one How to group multiple views in a ConstraintLayout
Related
Is there an easy way to switch between the displayed view in a ViewSwitcher in the Android Studio preview, or is the only way to swap out the XML for the sub-views one at a time?
Unfortunately, there are no XML attributes or any option on Android Studio which can help you to define the displayed view.
A similar question for the ViewFlipper was asked here (they both are direct subclasses of ViewAnimator).
However, if and only if your views are large as the screen, you could use the include tag, for example:
<ViewSwitcher
android:id="#+id/myViewSwitcher"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/first_view">
</include>
<include
layout="#layout/second_view">
</include>
</ViewSwitcher>
Then you can see your layouts in a separate XML file.
First of all if you are thinking to use ViewSwitcher, just for showing ProgressDialog then you are not doing it in a way in which it should be.
ViewSwitcher generally used to change layout of Activity. In your case ProgressDialog is not a View of your Activity rather it is just small helper which indicates some process is doing. So In short ViewSwitcher should be use somewhere where you want to alter complete screen of Activity.
In your case you can divide your layout into smaller layout files and group them using merge or include.
Create separate files for all different screens which will define UI of your Activity and group them using include.
For an example we can create small App for Introduction thing using ViewSwitcher -
First Screen - my_product.xml - this layout will define something about product.
Second Screen - about_us.xml - this layout will describe about your company.
Third Screen - thank_you.xml - to say thank you to your users.
Group them in any container View.
<ViewSwitcher
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/my_product"/>
<include
layout="#layout/about_us"/>
<include
layout="#layout/thank_you"/>
</ViewSwitcher>
ViewPager can easily solve your issues.
ViewPager (it can hold multiple views). ViewPager is kind of Array Container for View objects. You can have ViewPager rotation (like you do the array rotation) or other techniques to swap inside views. And, you can create your each inside views based on the Factory DP, so that there happens less processing (shares common resources).
They have mentioned swiping views here (Note: you just need own view swiping techniques if you don't want to use default ViewPager rotation).
Creating swipes: https://developer.android.com/training/implementing-navigation/lateral.html
ViewPager for screen slides: https://developer.android.com/training/animation/screen-slide.html
I have a fragment defined by the following xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_example"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_example"/>
</RelativeLayout>
Now I would like to reuse the ImageButton (and other buttons I will add) in another fragment, ideally
without copying its definition
by keeping the definition in xml and not adding it programmatically
I.e. the goal is to overlay the same set of buttons in different fragments.
Is there a way to define all buttons in a separate xml file and load them programmatically on fragment creation?
Yes, You can.
Define all buttons in different xml say layout_buttons.xml
and add them in each fragment layout using
<include layout="#layout/layout_buttons" />
I want to display two different activities in a single screen how can i do that in android?Please if anybody has idea share it.And I don't wanna use fragments.
I want to display a screen which contains some fields and below(at the bottom of the screen) I want another screen with some buttons.
Is this possible in android?
If so, How can i do this ?
You can't have two activities in one screen. You can have only one. So, ultimate solution is Fragments.
An activity is not directly a visual component, so I'm thinking that what you're really asking is how to have a single activity display different views.
There's nothing that says you can't rerun setContentView() with a different layout/view ID. But there's another non-fragments way of doing what your probably want.
You can define more than one full-size (match_parent) view in a layout. What you want to do is set the visibility for one of them to "visible" with android:visibility="visible" and all the others to "gone" with android:visibility="gone".
Then when you want to switch the displayed view, you'll run setVisibility(View.GONE) on the outgoing view and setVisibility(View.VISIBLE) on the incoming. It's important to use GONE and not INVISIBLE or the layouts won't render correctly.
Sample layout file:
<FrameLayout 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=".MainActivity" >
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
<SurfaceView
android:id="#+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<WebView
android:id="#+id/web"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
Sample Code to switch view:
video.setVisibility(View.VISIBLE);
img.setVisibility(View.GONE);
web.setVisibility(View.GONE);
That said, you probably want to learn how to use fragments since you can handle switching the view along with other state in a single unit of work (a transaction). But the above approach above does work for simple view changes.
I have 5 unique pages of xml that are fairly complex. I want to put the 5 pages inside a ViewPager. All of the samples I can find simply put identical contents in each page via code. I want to declaratively define the xml in the viewpager like the xml pasted below. But this does not work - the app stops with this xml.
If I can't declaratively define it, then can I load individual xml pages into the viewpager? I can find no examples that do this.
thanks,
Gary Blakely
<?xml version="1.0" encoding="utf-8"?>
<fragment >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/imageView1"
android:src="#drawable/flashright" android:adjustViewBounds="true" android:scaleType="fitXY">
</ImageView>
</LinearLayout>
</fragment>
<fragment >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/imageView1"
android:src="#drawable/flashleft" android:adjustViewBounds="true" android:scaleType="fitXY">
</ImageView>
</LinearLayout>
</fragment>
If I follow, you want to declare everything in XML and avoid any programmatic initialization from within your Activity containing the ViewPager. The only way I can think of doing this would be to define 3 different Fragment classes which reference 3 different xml layouts. You could then embed them in your above xml, replacing each <Fragment> element with <FragmentX> <FragmentY> <FragmentZ> etc. Personally, I would rather write 3 xml layouts and create a single Fragment implementation that takes a single int argument to designate which layout to load, and then do the small amount of programmatic initialization necessary to make such a solution work. The rationale being that there is less duplicated code.
EDIT:
Another approach that might more fully address your requirements is to replace your <Fragment> tags with <Layout> tags and give them id's. Then in your Activity code, store refs to them, remove them from the View in onCreate() and finally add each of the stored references into programmatically created instances of Fragment which you then add to your ViewPager. Very ugly but thats the only way I know of to declaratively define everything in XML. You'll still have the problem that its not clear from the XML that these elements are nested within a ViewPager so personally I don't see the point. ListView and ListFragment operate with the same kind of implicit association though so its not unprecedented.
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
The RED area will be different for all other screens. It may contain data like following screens mockups:
Activity One loaded into main container
Activity Two loaded into main container
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.
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
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'...