I'am stuck!
I am developing my first Android App, so I am considered as a beginner. I have some programming background, so I managed to solve the first problems myself. But now I am at a point where I don't know how to solve several problems. So please share your eternal wisdom with me.
I am developing a game. I want the menu to be in a virtual phone. The picture below describes best what I want to achieve. Don't be confused by the words, I am from Germany.
Einstellungen = preferences ...
http://www.directupload.net/file/d/3565/2xwgz3al_png.htm
When I am pressing the menu-button a fragment gets called. At the moment the layout of the fragment contains relative layout with android : background set to that entire image. What I want to achieve is that the phoneframe stays all the time, only the view (RED) will change. With up and down buttons I want to be able to move the chooser (BLUE) to the different menuitems. If I press OK (YELLOW) the selected item is called an e new view slides from the right side in the RED area. Hope that's clear.
So my questions are:
How do I get the RED area to that phoneframe? Maybe a LinearLayout with fixed Width and Height? But i cant image that as a good solution.
How do I animate the chooser (Blue) to the different menupoints by clicking up and down?
How would you perform the switch between the views inside of the phone Frame.
I want to perform all of that in that only fragment. Or is there a better solution?
I do not need the code for that all, only a push, a start or ideas so I can start googleing in the right directions.
Big Text an many questions, I hope you can take a little time for me, THANKS for answers.
Greetings from Germany (sorry if my English is not perfect)!
Well you are asking a lot of question at once so it's difficult for me to give a clear answer. I am just going to explain to you how I would build a screen like that:
1) The Layout:
You Layout can simply be built with a RelativeLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/flFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_marginTop="64dp"
android:layout_marginLeft="64dp"
android:layout_marginRight="64dp"
android:layout_marginBottom="128dp"
android:background="#ff0000"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="#+id/btnDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="15dp"
android:text="#string/fragment_main_button_down_text"/>
<Button
android:id="#+id/btnUp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/btnDown"
android:layout_centerHorizontal="true"
android:text="#string/fragment_main_button_up_text"/>
<Button
android:id="#+id/btnClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/btnDown"
android:layout_alignParentBottom="true"
android:text="#string/fragment_main_button_close_text"/>
<Button
android:id="#+id/btnOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/btnDown"
android:layout_alignParentBottom="true"
android:text="#string/fragment_main_button_ok_text"/>
</RelativeLayout>
</RelativeLayout>
So the layout is not that complicated, I set the background color of the FrameLayout to white so you can see were the fragment will be placed. Here is the Result:
This layout contains the buttons ok, close, up and down and of course a FrameLayout where our fragment is going to go. The layout in this example is by far not optimal, the problem is the positioning of the FrameLayout. It is as big as the screen with a fixed margin on all sides, so on different phones with different aspect ratios the FrameLayout is also going to have a different aspect ratio.
2) The FragmentTransaction
Now comes the interesting part, we are going to put our fragment into the FrameLayout container. But first, since we want the fragment to slide in from the right we have to write an ObjectAnimator like this:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:propertyName="xFraction"
android:valueType="floatType"
android:valueFrom="1.0"
android:valueTo="0.0"
android:duration="750" />
This describes a translation animation from right to left, if you want more information on that feel free to ask.
Now with that animation we have everything we need, now whenever you want to change the Fragment inside the phone you just have to perform a FragmentTransaction like this:
// We get our FragmentManager and begin our transaction
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
// Here we set our animations, to make the effect nicer I added a fade out animation for the old fragment
// The fade out animation is already built into Android
transaction.setCustomAnimations(R.animator.slide_in_right, android.R.animator.fade_out);
// We specify were we want the Fragment to go and pass along our new fragment instance.
// Calls to replace(), add(), remove()... always have to take place AFTER setCustomAnimations()
// Otherwise the animations are not applied to the fragments
transaction.replace(R.id.flFragmentContainer, fragment);
// With commit() the transaction is actually executed. You can replace multiple fragments in a single transaction
transaction.commit();
And here is the result, in my example app the FragmentTransaction is executed every time I press OK:
Related
I am looking for solution as on images bellow:
I need to have two resizable views in one layout.
User just needs to move separation line to the top (ScrolView B becames higher) or to the bottom (ScrolView A becames higher).
What is the best solution, which gives this behavior? I know that I can extends from ScrollView and override public boolean onTouchEvent(MotionEvent ev) and protected void onDraw(Canvas canvas), but may be there is more simple solution. I want to avoid calculation the math of moving. Thank you for any information.
If you want to solve this problem quickly, I suggest you use Split Pane Layout.
Usage :
<com.mobidevelop.spl.widget.SplitPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:spl="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="#+id/splitPaneLayout"
android:layout_height="match_parent"
spl:splitterSize="12dp"
spl:orientation="vertical"
spl:splitterPosition="50%"
spl:splitterBackground="#781b23">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="" />
</ScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text=""/>
</ScrollView>
</com.mobidevelop.spl.widget.SplitPaneLayout>
I solved your problem by creating two xmls for portrait and landscape mode. For portrait mode, i set the panel's orientation as vertical by adding spl:orientation="vertical" and for lanscape mode, i set the panel's orientation as horizontal by adding spl:orientation="horizontal".
After doing all this, I got the look like below.
Made this into an answer.
You basically want the split screen view from Android N. You could base your code off the open source implementation in SystemUI:
http://androidxref.com/7.1.1_r6/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
Along with this for the handle:
http://androidxref.com/7.1.1_r6/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
You can throw away all code that has to do with stacks (which is the row of screenshots off different activities in your history), buss events and anything that has to do with running another activity, such as the code for Vsyncing between apps (mSurfaceFlingerOffsetMs).
It should leave you with quite small and easy to use classes.
I am creating an app which does some tracking on a map. The tracking part works great inside my activity.
However, I want to have some kind of small overlay in the bottom right corner (like the minimalised video playback in the YouTube app) that stays there, even when I switch activities.
I have looked at this, but it's not really what I need. I don't need it to be moveable, and I think this is impossible to keep when switching activities.
Is there some kind of class that I can implement (Widget, Fragment, ...) that would fit my needs?
Thank you,
DebboR
This is a bit late and probably not relevant to you anymore, but maybe somebody else will find this helpful.
I don't think it's possible to switch activities and keep a certain view on screen. How I think this should be done is have a main activity with fragments that swap and in the activity's layout have a view overlay on top of the fragments container.
For example:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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">
<!-- Container for the fragments -->
<FrameLayout
android:id="#+id/fragment_container"
android:layout_below="#id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- This view will overlay the fragment in the bottom right corner -->
<View
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
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.
My FragmentActivity displays one Fragment at the beginning and a second when I press a Button. Until here, it's easy. But I got one problem with the animations.
I add the second fragment with:
mTChild.add(R.id.container, mFragChild).addToBackStack(null).commit();
And to make it more "alive", I declare a CustomAnimations before adding the Fragment, it looks like this:
mTChild.setCustomAnimations(R.anim.slide_in, R.anim.alpha_out, R.anim.alpha_in, R.anim.slide_out);
mTChild.add(R.id.container, mFragChild).addToBackStack(null).commit();
I used this method setCustomAnimations(int,int,int,int) (parameters: enter, exit, popBack enter, popBack exit) as you can see on setCustomAnimations Documentation. Just to understand my (basic) animations xml:
slide_in > the new fragment slide from right to left.
slide_out > back stack = fragment slide from left to right.
alpha_out > the old fragment disappears with alpha 100 --> 0.
alpha_in > back stack = old fragment appears with alpha 0 --> 100.
At this step, I got what I want a slide in/slide out from right for the new fragment which takes place above the old fragment. But the effect for the old fragment which normally stays behind and disappears/appears with the alpha not happens.
What I am doing wrong? Because, the CustomAnimations happens but not for the old fragment (which it not removed).
Thanks for your answers.
I feel shame, I did a stupid mistake!
First of all:
Obviously I can't do this like I did, because the old fragment stays behind. So it can't make an out animation.
I answered at my own question when I asked it: "the old fragment (which it not removed)"... my god! So instead of:
mTChild.add(R.id.container, mFragChild).addToBackStack(null).commit();
I should do:
// REPLACE (remove+add) and not ADD only !
mTChild.replace(R.id.container, mFragChild).addToBackStack(null).commit();
If I want an out animation.
Nice effect:
I found an elegant way! Indeed, the goal was to keep the first Fragment visible, overlapping with a new Fragment (a ListView) and make the older less visible to 10% (for giving a shadow/under effect). I was wrong on the way to do this.
Inspired by SlidingMenu and this answer Generate an overlay slide in and move existing Fragment to left, I created a FrameLayout to add() (this time no doubt) the new Fragment which have a View to the left with a gradient background to make the shadow effect.
With this:
mTransaction.add(R.id.container, mChildA, null).hide(mChildA)
.add(R.id.container2, mFrag, null).commit();
And after, when I press my Button, I do as below:
mTChild.setCustomAnimations(R.anim.slide_in, 0, 0, R.anim.slide_out);
mTChild.show(mChildA).addToBackStack(null).commit();
In fact, I have the slide in and the reverse effect with the BackStack, and I overlay my content with a shadow on the left side. The xml of my Fragment it's now:
<RelativeLayout
android:layout_width="match_parent" android:layout_height="match_parent" >
<View
android:id="#+id/shadowLeft"
android:layout_width="50dip" android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:background="#drawable/fragment_shadow_left" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="#id/shadowLeft" />
</RelativeLayout>
Finally, I make the FrameLayout to "host" this layout above, with a background transparent and it works perfectly.
If someone wants to edit or give a better answer, I'm always listening. Hope this will be useful for someone who searches the same effect.
Have you considered using the method called "replace" instead of "add" in order to change your fragments?
i am targeting an app on android 2.1. i am having a layout which contains three sections. the header, mainbody and the footer. the footer remains same all through the application lifecycle. the footer has four options for the user to select(like four tabs). when the user selects each option in the footer the content has to change in the mainbody. and when the user interacts with the UI in the mainbody, there is a need to change the content of just the mainbody(like activity replacing an activity). and the user selection in the footer has to remain highlighted untill user selects another option in the footer.i alomost have a need like, launching activities within the same tab, but the tabs are placed below. a lot of people have suggested using activitygroup but as it is deprecated how do i go about doing this?. if anybody needs more clarity about question i am ready to provide
If you want support from lower versions like 2.1 and higher I can propose my way. I always use separate XML layout for tray (footer in your case), for example (res/layout/tray.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainMenu"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#EEEEEE"
android:gravity="bottom|fill_horizontal"
android:orientation="horizontal"
android:padding="5dp" >
<ImageView
android:id="#+id/addBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/add" android:layout_weight="0.2"/>
<ImageView
android:id="#+id/catalogBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/catalog" android:layout_weight="0.2"/>
<ImageView
android:id="#+id/searchBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/search" android:layout_weight="0.2"/>
<ImageView
android:id="#+id/settingsBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/settings" android:layout_weight="0.2"/>
<ImageView
android:id="#+id/infoBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/info" android:layout_weight="0.2"/>
</LinearLayout>
And includes it in every Activity I need:
<include layout="#layout/tray" android:id="#+id/tray" />
After that I can in java code hide/show some buttons in tray by ID, or select some of them with another color ...
To display the footer menu across all activities, you may create a custom layout - the layout of the footer - and include it in every activity, or to be more specific, include it in the layout of every activity with <include />
Also, all your activities should have a parent activity, let it be BaseActivity, where you will provide appropriate actions for you footer menu.
Then you will need just to inherit the BaseActivity and include the footer menu layout, into your current layout, to have the menu available for any Activity you would like.
Another possible approach is using fragments instead of a full activity per content page. Fragments are a lot like activities, except that they need to be embedded in an activity to be displayed and they give you the freedom to change the content of one part of an activity (that is, swapping one fragment for another), meaning you can have another part of the activity remain unchanged - for instance tabs for switching between these fragments. A nice bonus is that reusing that content page in another activity is very easy, and should you choose create a tablet-friendly version you can easily compose more complex views of your existing fragments.
Using a ViewPager together with some type of page indicator, such as the tab indicator here you can have an active fragment and easily switch between them.
Since you are targeting 2.1 you will need to use the android support library to support fragments.