I'm inflating an AlertDialog to let the user send comments. Fairly simple. But I'm getting this Lint warning:
Layout uses the wrong button order for API >= 14: Create a layout-v14/chat_comment_dialog.xml file with
opposite order: Cancel button should be on the left (was "#string/send | Cancel", should be "Cancel | #string/
send")
So, yeah, this is the solution, create a specific layout for API >= 14 and invert the order. But....REALLY? Is this REALLY the official suggestion? To set one order in some devices and a different one in others? As a user, I would feel very confused. Should I ignore this Lint advice, or otherwise, follow this new pattern for a set of devices (which I think is rather confusing)
Anyway, here's the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp" >
<EditText
android:id="#+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/username"
android:singleLine="true" />
<EditText
android:id="#+id/message"
android:layout_width="match_parent"
android:layout_height="180dp"
android:gravity="top|left"
android:hint="#string/review" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingRight="4dp"
android:text="#string/send"
android:textSize="18sp" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="4dp"
android:text="#android:string/cancel"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
By the way, I have to inflate the Buttons in the XML and not in the AlertDialog.Builder (maybe this way the buttons will be automatically order themselves), because any onClickListener you set to the Builder's deafult button will dissmiss the dialog, and I have to avoid that behaviour to control the Dialog myself.
If you plan on targeting API level >14 then you should definitely follow the design specification. Changes were made to the layout of dialogs to increase usability.
As a user you would not be confused because you are only using a single device at a single API level. What is confusing is when a developer create non-standard UI's. Not following the standard will lead to frustration and confusion. For example if all the other apps on a user's phone (API level >14) create standard dialogs with the proper button order and your app has the button order wrong it lead to users hitting Cancel instead of Send and visa versa. Surely this will confuse and annoy the user.
It really isn't that much extra work to check the API level on the device and to provide the appropriate layout. If you design your app well it shouldn't require more than a few lines of code.
Regarding your last comment, you can still do all the AlertDialog stuff from code and be able to control things like when the dialog is dismissed, just use a View.onClickListener instead of DialogInterface.onClickListener:
AlertDialog d = new AlertDialog.Builder(context)
.setPositiveButton(R.string.button_text, null).show();
and then add the listener afterwards:
d.getButton(AlertDialog.BUTTON_POSITIVE)
.setOnClickListener(new View.onClickListener() {...});
Adding the alternative listener prevents the dialog from automatically being dismissed when the button is pressed.
Related
We're developing an app where we need to use a custom font (a Typeface loaded from the app's assets) in an EditText. The Android input method docs state the following:
When input focus moves into or out of an editable text field, Android shows or hides the input method (such as the on-screen keyboard) as appropriate. The system also makes decisions about how your UI and the text field appear above the input method. For example, when the vertical space on the screen is constrained, the text field might fill all space above the input method.
It's the part in bold that is tripping us up. The phrase “the text field might fill...” appears to be misleading, in that the text field that's used is not the EditText that we set up with our custom font. (NOTE: the answers so far all explain how to set a custom font in an EditText. We already are setting a custom typeface in the EditText. Please read the question carefully before answering.) Here's a screenshot with the input method hidden:
Here's what happens when the soft keyboard is showing and vertical space is constrained:
As you can see, the font in the text field above the input method is not our custom font (I'm guessing it's the system's default Roboto font). This is happening for every soft keyboard we've tried as the input method.
I want to emphasize that when space is constrained, this view above the keyboard is generated internally by the system, not by any of our code.
The main question is: Is there a way (and, if so, what is it?) to control the appearance of this (for lack of better terminology) proxy view—at a minimum to get it to use our custom font?
It would be an added bonus if we could also control the layout and appearance of the entire proxy area above the keyboard (including the "Done" button). We are using a variation of the technique described in this thread to have our activity use a locale different from the one set in the system, but the activity's locale clearly isn't being applied here. (If it were, the button would be on the left and would read "בוצע", as does happen if I change the device's locale to Hebrew. [EDIT: I can get the correct button label by using the android:imeActionLabel attribute on the EditText. However, I don't know how to control the layout directionality.])
EDIT Per request, here's how I'm constructing my dialog (relevant parts excerpted from a DialogFragment):
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dlg = new Dialog(getActivity(), android.R.style.Theme_Holo_Light_Dialog_NoActionBar);
dlg.setContentView(R.layout.edit_note_dialog);
mAnimator = (ViewAnimator) dlg.findViewById(R.id.animator);
final Typeface hebrew = SystemData.getHebrewFont();
mNoteEditor = (EditText) dlg.findViewById(R.id.note_field);
mNoteEditor.setTypeface(hebrew);
// etc. (setting fonts for other elements, adding listeners, etc.)
}
And here's the layout:
<?xml version="1.0" encoding="utf-8"?>
<ViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/animator"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingTop="10dp"
android:text="#string/loading" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#android:color/black"
android:gravity="center"
android:text="#string/edit_note_title"
android:textColor="#android:color/white"
android:textSize="20sp" />
<TextView
android:id="#+id/citation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/title"
android:layout_centerHorizontal="true"
android:background="#android:color/black"
android:gravity="center"
android:textColor="#android:color/white"
android:textSize="16sp" />
<LinearLayout
android:id="#+id/actions"
style="?android:attr/buttonBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_margin="5dp" >
<Button
android:id="#+id/cancel"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:gravity="center"
android:minWidth="32dp"
android:text="#string/cancel"
android:textSize="#dimen/nav_interior_item_size" />
<Button
android:id="#+id/close"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:gravity="center"
android:minWidth="32dp"
android:text="#string/save"
android:textSize="#dimen/nav_interior_item_size" />
</LinearLayout>
<Button
android:id="#+id/undo"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_margin="5dp"
android:text="#string/edit_note_undo"
android:textSize="#dimen/nav_interior_item_size" />
<Button
android:id="#+id/redo"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_margin="5dp"
android:text="#string/edit_note_redo"
android:textSize="#dimen/nav_interior_item_size" />
<EditText
android:id="#+id/note_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/actions"
android:layout_below="#+id/citation"
android:focusableInTouchMode="true"
android:gravity="top"
android:hint="#string/edit_note_hint"
android:imeActionLabel="#string/done"
android:inputType="textMultiLine|textNoSuggestions"
android:lineSpacingMultiplier="1.2" />
</RelativeLayout>
</ViewAnimator>
It would be simple if you had an instance of InputMethodService.
There is a way to set a theme or even set extracted view.
The problem is you have to create a custom implementation of Input Method and users will have to select it in the system settings.
Update:
You can try with:
android:windowSoftInputMode="adjustResize"
make the view scrollable
or
use IME_FLAG_NO_EXTRACT_UI
set an OnEditorActionListener on the EditText to have an action button on the keyboard.
create custom layout or hide/show elements when screen's height is too small. For example hide buttons at the bottom and show buttons on right side. It can look similar to the default extract view.
layout listener for the dialog or EditText:
mViewContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
//unregister the layout listener if needed.
int heightPixels = mViewContainer.getHeight();
Resources resources = mContext.getResources();
int heightDip = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, heightPixels, resources.getDisplayMetrics());
if (heightDip < MIN_HEIGHT) {
mBottomButtons.setVisibility(View.GONE);
mSideButtons.setVisibility(View.VISIBLE);
} else {
mBottomButtons.setVisibility(View.VISIBLE);
mSideButtons.setVisibility(View.GONE);
}
}
});
Changing the visibility to GONE will request relayout and the listener will run again what can lead to a loop.
The only way I can see is to disable the fullscreen editing mode for your EditText that automatically kicks in when your EditText is not tall enough.
mNoteEditor.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
You can fix the dialog resizing issues with
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Your dialog layout should probably be enclosed in a ScrollView.
I think as other have stated this is unfortunately up the IME and may not be possible through supported APIs.
Beware, hacky and untested solution incoming:
Digging through the Android source code, I found that every IME contains an implementation of AbstractInputMethodService. Android provides a standard implementation (android.inputmethodservice.InputMethodService) which if you look at, has a public setExtractView method, and an onCreateExtractTextView method, which inflates com.android.internal.R.layout.input_method_extract_view.xml, which in turn contains com.android.internal.R.id.inputExtractEditText! So a hacky solution would be to hope that most of your customer's IMEs' InputMethodServices use this same XML (which as far as I can tell, has been in Android for a while), and you can attempt to grab a reference to this EditText by it's ID and change it's typeface. Unfortunately I'm not sure offhand where in the view hierarchy/window the views of an InputMethodService are added, and if they're accessible from your app/activitys process.
Source for InputMethodService:
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/inputmethodservice/InputMethodService.java
Source for the layout XML:
https://github.com/android/platform_frameworks_base/blob/master/core/res/res/layout/input_method_extract_view.xml
If you really want to get yourself in trouble, perhaps there's a way to get a reference to the IME service itself, and use reflection to alter the extracted view. The standard InputMethodService holds a package-private reference to mExtractEditText :)
I know not the answer you're looking for but perhaps it'll put you in the right direction...or some direction at least.
If you have a single editable element on your Dialog, how about handling orientation changes and
in case of Portrait orientation, show the Dialog
in case of Landscape orientation, show a fullscreen Fragment with the EditText and Buttons (as others have stated; disable fullscreen editing mode for the EditText), request focus for the EditText, show Keyboard.
in case of orientation switching dismiss Dialog / show Fragment with the already entered text (and vice versa)
This might be conceptually good because if the user wishes to enter text, he/she will always end up in a fullscreen editing layout in Landscape orientation. And since there is only one editable view in the original Dialog, you don't explicitly need the Dialog to select anything else to edit (another EditText for example).
I have 2-3 Activities in my app that all share data in a memory pool. I want to be able to easily switch between these activities while keeping them all simultaneously running. In addition, I am developing for Android 4.0. I would like to use TabActivity, but it has been deprecated and replaced with ActionBar, which I have tried but I don't think it's what I'm looking for. I want large tabs, similar to the classic "Artist/Playlist/All" tabs found in the stock Android Music Application, or like the Tab Bar seen at the bottom of the screenshot below. Does anyone know of a library to create these tabs or a way to make ActionBar more customizable? Or is using TabActivity a perfectly good solution, even on ICS devices?
ActionBar is what you're looking for, actually.
You should convert your Activites to Fragments. Assuming they're not too complex, this shouldn't be hard at all. There are tons of examples out there. You need one Activity, preferably a FragmentActivity, to hold all of them.
This should help:
http://arvid-g.de/12/android-4-actionbar-with-tabs-example
There are several subquestions to this, I'll try to address them all:
-In order to use the top tabs, you want to use an ActionBar.
-If you were to do it in the style of the music app, where you swipe sideways between views and the label of the current one is always front and center... For that, the class you'd want to use is called ViewPager
You can see all of these methods by creating a new Activity in eclipse, and going through the wizard. Under "Navigation Type" you can select "Tabs", "Tabs + Swipe", "Swipe Views + Title Strip". Create any one of those Activities to see how it looks, and then look at the code to see how it's implemented & how to customize it.
-Navigation along the bottom is discouraged- See the Android Design Guide, spec the section "Don't use Bottom Tab Bars"
You have probably found an answer by now, but I thought I'll share another way you could create something like that tab bar using images and xml:
<?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:orientation="vertical"
android:id="#+id/main">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#drawable/tabackground"
android:layout_alignParentBottom="true"
android:id="#+id/llBottom">
<ImageButton
android:src="#drawable/icon2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
/>
<ImageButton
android:src="#drawable/icon3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
/>
<ImageButton
android:src="#drawable/icon4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
/>
<ImageButton
android:src="#drawable/icon5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
/>
</LinearLayout>
<ImageView
android:layout_height="24dp"
android:layout_width="fill_parent"
android:layout_alignTop="#+id/llBottom"
android:background="#10ffffff"/>
<ImageView
android:layout_height="1dp"
android:layout_width="fill_parent"
android:layout_alignTop="#+id/llBottom"
android:background="#30ffffff"/>
</RelativeLayout>
Is not perfect but with some creativity and changing some values it can look very good.
Hope it helps in some way.
I'm building a new application to the Android platform and I need to add an interactive movie that would show to the user, how to use the application.
I want something like the video in Angry Birds, with the button that spreads to the outside of the dialog.
Like this:
First I though that I need some kind of a animation video, so I checked the Android video view, but I can't figure out how to use it, and if I actually need it?
Secondly is this window is a regular dialog or something else?
I tried the regular dialog but I didn't came with the idea of this button, all the buttons is inside the dialog itself and I can't show it like I wan't (e.g. Angry Birds dialog).
Any help will be great, Thanks.
EDIT: This is the custom dialog:
<?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" >
<TextView
android:id="#+id/videoView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Test Test"
android:textSize="50dip"
android:textColor="#android:color/white"/>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="#id/videoView"
android:layout_marginBottom="20dp"
android:layout_marginRight="85dp"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
And this is what I get:
Angry birds doesn't use the the Android Ui elements. They use a custom framework to show their dialogs. Therefore you will need to customize your own dialog as well.
If you your application really needs a video to demonstrate its use, maybe you should reconsider your application functionallity. Maybe a simple application will do with a set of screenshots and annotations.
There are two numbers constantly displayed in my UI. I need the user to be able to specify those numbers. In a desktop app I simply use 2 spinbuttons, and can beat it (I guess). However, there are problems with this in Android (I am targeting Android 3-based tablets).
First of all, I've tried NumberPicker widget, but it simply does not show itself properly (I've asked a question about it, but no response so far).
Then I've tried some 3rd-party numberpicker implementations one cand find on the Web, but for various reason didn't like neither of them. Some of them are too large to fit the side panel I'm squeezing controls into, some are just ugly (and too small, probably), and all of them automatically grab input focus causing the keyboard to show every time I open this side panel.
There is another option - only show the uneditable label with a number on the panel, and show popup window with some numberpickers in it. Apart from me not knowing how to implement such a popup (just learning), how do I decorate the label so that the user understands he can tap it to edit?
Perhaps, there are better solutions for this problem? I took a look at some apps from Google Market, and they all seem to either use huge NumberPickers at the center of the screen (and I need as much of the screen as possible clear), or a popup with the same huge Numberpickers I don't particularly like.
Can you suggest anything else? Thanks in advance!
There are two different issues in your question:
For the number picker for eaxmple in my case I have created a simple tool. You can just put a button with the text "-" then a textview and then a button with "+". You put it in a linear layout and t can be vertical or horizontal. If you want it you can make it very small. For example here is what I have wrote but you can try playing with the options to see which is better for you.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<LinearLayout android:orientation="vertical" android:id="#+id/linearLayout1"
android:layout_width="wrap_content" android:layout_weight="1"
android:layout_height="wrap_content">
<Button android:id="#+id/button22" android:layout_gravity="center"
android:layout_weight="1" android:text="+" android:gravity="center"
android:layout_width="30dip" android:layout_height="30dip"></Button>
<Button android:id="#+id/button11"
android:layout_gravity="center"
android:layout_weight="1" android:text="-"
android:gravity="center" android:textAppearance="?android:attr/textAppearanceSmall" android:layout_height="30dip" android:layout_width="30dip"></Button>
</LinearLayout>
<LinearLayout android:id="#+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" android:orientation="vertical">
<Button android:layout_weight="1"
android:layout_height="fill_parent"
android:layout_width="30dip"
android:text="0" android:id="#+id/quantidad"></Button>
</LinearLayout>
then you can add onClick listeners on the buttons and setup to increase or decrase the text displayed in the text view.
As for the keyboard well if you use that example you not need it but if you use an edittext then you can setup an option for the keyboard to be hidden in the manifest: you can see the option here http://developer.android.com/guide/topics/manifest/activity-element.html
I am looking for a view or some sort of information regarding the bottom bar in default applications of Android such as Email, or Unlock pattern as shown in the picture below. I have not been able find anything about this on Androids site nor from Google searches.
Image: http://img11.imageshack.us/i/viewdn.jpg/
I believe that Christopher is correct; there is no special widget to create the bar in your image. However, if you want to emulate it, you can create a layout and use the style style="#android:style/ButtonBar". That will give you the light gray background and the correct margins.
I don't believe there's any standard view for the button bar used at the bottom of these apps; it's generally just two Button items placed together in a LinearLayout or RelativeLayout.
For example, looking at the Android Open Source Project, you can see the button bar for one of the email app setup screens is defined as two plain old Button objects.
However, it is surprising that Google didn't abstract more of the common stuff into an Android theme or sublayout, rather than having the same views and attributes in each layout XML.
From: http://code.google.com/p/k9mail/source/browse/k9mail/trunk/res/layout/account_setup_basics.xml?r=1314
<RelativeLayout
android:layout_marginTop="-45dip"
android:padding="0dip"
android:layout_alignParentBottom="true"
android:gravity="bottom|right"
android:background="#android:drawable/bottom_bar"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<Button
android:id="#+id/manual_setup"
android:text="#string/account_setup_basics_manual_setup_action"
android:minWidth="#dimen/button_minWidth"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginBottom="-4dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="false"
/>
<Button
android:id="#+id/next"
android:text="#string/next_action"
android:minWidth="#dimen/button_minWidth"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:drawableRight="#drawable/button_indicator_next"
android:layout_marginBottom="-4dip"
android:layout_alignParentRight="true"
android:layout_centerVertical="false"
/>
</RelativeLayout>