I'm having a strange problem with certain phones with different keyboards to that of Google/Samsung that I was wondering if anyone had encountered and had a solution for.
The problem I'm encountering is this: If I use the stock google or Samsung galaxy's keyboard, my layout (below) performs fine, is snappy and there are no lags whatsoever. I tested this on many devices (Galaxy S3, Galaxy Note, Galaxy S5, Nexus 5, 6 and 7). If I run this on an HTC or an LG phone on the other hand with their default keyboard, the layout has a visible lag when users enter text.
After lots of debugging and performance measurements, I found out that the problem is with the suggestion bar. For the default Samsung/Google keyboards, the suggestion bar is always present (shown below) but for the HTC/LG phones, the suggestion bar only becomes visible once the user types something which causes a re-render of the layout. This re-render in turn causes noticeable lag when the user starts typing. I've tried many, many solutions found here on SO such as wrapping my layouts in LinearLayout and fixing their widths (by specifying weights) and fixing heights of other controls, etc (all visible in the layout file below) in order to remove the burden of measuring the layout measurements but none of them have removed this lag.
My question is, how would I fix this problem? Is there a way to force ALL keyboards to always show this suggestion bar regardless of the fact that there may or may not be any text entered by the user? It's not really an option for me to force my users to choose a specific keyboard or else they face considerable lag.
My layout is a simple layout with a horizontal scroll view and two edit texts:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/editText_topic"
android:textSize="#dimen/txt_description_font_size" />
<HorizontalScrollView
android:id="#+id/layout_topics"
android:layout_width="match_parent"
android:layout_height="#dimen/gallery_height"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="2dp"
android:background="#drawable/rectangle_error_background"
android:paddingLeft="6dp"
android:paddingRight="6dp" >
<LinearLayout
android:id="#+id/gallery_topic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="horizontal" />
</HorizontalScrollView>
<RelativeLayout
android:id="#+id/layout_title_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="8dp" >
<TextView
android:id="#+id/txt_title_length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textSize="#dimen/length_text_font_size" >
</TextView>
</RelativeLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/txt_title"
android:layout_width="0dp"
android:layout_height="#dimen/txt_input_height"
android:layout_gravity="fill_horizontal|fill_vertical"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:hint="#string/editText_title_hint"
android:inputType="textFilter|textCapSentences" >
<requestFocus
android:layout_width="match_parent"
android:layout_height="match_parent" />
</EditText>
</LinearLayout>
<RelativeLayout
android:id="#+id/layout_description_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="8dp" >
<TextView
android:id="#+id/txt_description_length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textSize="#dimen/length_text_font_size" >
</TextView>
</RelativeLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/txt_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="top|left"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:gravity="top"
android:hint="#string/editText_description_hint"
android:inputType="textAutoCorrect|textCapSentences|textMultiLine"
android:scrollbars="vertical" >
</EditText>
</LinearLayout>
</LinearLayout>
The activity in manifest is this:
<activity
android:name="MyActivity"
android:icon="#drawable/whatever"
android:label="#string/empty"
android:parentActivityName="ParentActivity"
android:theme="#style/MyTheme"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
Update:
I've noticed WhatsApp always shows this suggestion bar on the keyboards even though the EditText's input is empty (user has not yet entered a value). Does anyone know how that's done?
Many thanks in advance.
There is no way to force it. That's something that has to be done on the keyboard side, as the keyboard decides when to show the candidatesView. In fact this performance issue is a reason why on several of the keyboards I worked on we didn't use the Android built in candidatesView functionality and rolled our own.
The following settings will hide the suggestion bar. However, I do not know a setting to force it to show.
android:inputType="textNoSuggestions"
android:inputType="textFilter"
Related
So I have this STRANGE issue happening on a galaxy tab (not sure if it's also happening on other tablets, but it doesn't on my nexus 5).
Here's a preview of my layout in android studio:
The XML for a row with white background is like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="horizontal"
>
<TextView
android:id="#+id/first_name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/content_spacing_normal"
android:textColor="#color/gray_dark"
android:textSize="#dimen/font_size_normal"
android:text="#string/form.label.first_name"
/>
<EditText
android:id="#+id/first_name_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="#dimen/content_spacing_normal"
android:background="#null"
android:ellipsize="end"
android:textColor="#color/purple"
android:textSize="#dimen/font_size_small"
android:layout_weight="1"
android:gravity="right"
android:hint="#string/form.placeholder.first_name"
>
</EditText>
</LinearLayout>
On the Galaxy Tab, the layout looks like this:
What's even stranger is that it displayed properly a couple of times, randomly, but most of the time the white background color doesn't seem to propagate to it's children.
Thanks in advance.
I'm working on a ListView where each item has an image and some text. On my older phone, HTC Evo 4G, things came up exactly as expected. Image is nicely sized and text looks fine. Then I loaded the same app on my new phone, HTC One, and the images are so tiny they are useless. I know the HTC One has a significantly higher resolution, but I cannot figure out how to make each item in the ListView larger.
I'm not sure what to post, but I think the layout xml files are the issue.
Here's activity_main.xml:
<?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">
<LinearLayout android:id="#+id/LinearLayout01"
android:layout_height="wrap_content" android:orientation="horizontal"
android:layout_width="fill_parent" android:gravity="center_horizontal"
android:layout_marginTop="2dip" android:background="#669900">
<!--
Use layout_weight to stretch the EditText and compress the button.
To avoid text wrap, the editable text is forced to occupy only one
line
-->
<EditText android:layout_width="wrap_content"
android:typeface="normal"
android:layout_weight="1" android:lines="1" android:ellipsize="middle"
android:hint="#string/hint" android:id="#+id/search_key" android:layout_height="fill_parent" android:maxLines="1"></EditText>
<ImageButton android:layout_width="wrap_content" android:src="#drawable/ic_menu_search" android:adjustViewBounds="true"
android:layout_weight="0" android:id="#+id/btn_ok" android:layout_height="wrap_content"></ImageButton>
</LinearLayout>
<TextView android:layout_height="wrap_content" android:id="#+id/tweet_header"
android:gravity="right" android:layout_width="fill_parent" android:paddingRight="4dp"
android:background="#99cc33" android:textColor="#000000" android:textSize="21dp"></TextView>
<ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/tweet_list"></ListView>
</LinearLayout>
And the ListView is made up of this item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/itemImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:scaleType="fitCenter"
android:src="#drawable/ic_launcher" />
<TextView
android:layout_height="wrap_content"
android:id="#+id/created_at"
android:text="now"
android:textSize="10sp"
android:layout_below="#id/itemImage"
android:layout_alignParentRight="true"
android:textStyle="italic"
android:layout_width="wrap_content"></TextView>
<TextView
android:id="#+id/itemURL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="itemURL"
android:visibility="invisible" />
</RelativeLayout>
So the app does this: It taps ebay for car data and presents the search results as line 1 with a picture, line 2 with the ebay item title. A hidden value is the URL so users can tap the ListView line and launch a web browser.
Looks like the wrap_content setting for the ImageView's layout_width and layout_height are the issue. When I switched that to numerical values, suddenly I saw it change size. Finally setting it to 100dp made the images viewable.
As an aside, I had a terrible time with ADS and the emulator. It consistently failed to re-load my updated app. Often complaining about the Package Manager and suggesting the some process was running. I little idea what was running and how to fix it. When I switched to loading the app straight to the phone, then it worked fine.
So, I think now I need to create a system that is proportional, and takes in to consideration the displaying devices resolution.
Problem is the Relative Layout width being wrap_content. Try changing that to match parent. then you would not have to go thru this ordeal
I am having a problem running a simple setRotation on a linear layout that houses a fragment.
Running on a galaxy S3 and ticking disable hardware overlays in developer options makes everything work really smoothly, without it, it causes only portions of the view to be displayed in a haphazard patch type display when in landscape.
The reason i am rotating the view and adjusting its layout parameters is because there is a list that i need to have visible with the items the user has selected even during screen rotation.
the view is displayed above a camera surface.
The xml layout of the view:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/occasionsOptionsLinearLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:gravity="top"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:id="#+id/whatOccasionTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="left"
android:padding="8dp"
android:text="#string/whatstheoccasion"
android:textColor="#color/Black"
android:textSize="#dimen/textMedium" />
<ImageView
android:id="#+id/occasionTitleImage"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="2dp"
android:layout_weight="0.3"
android:padding="2dp"
android:src="#drawable/mood" />
</LinearLayout>
<ScrollView
android:id="#+id/occasionscrollView"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:fillViewport="true" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
<fragment
android:id="#+id/occasion_fragment"
android:name="com.myapp.record.Occasions"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="#+id/occasionaOptionsClose"
android:layout_width="fill_parent"
android:layout_height="55dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
android:id="#+id/occasionsOptionsCloseAction"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:src="#drawable/close" />
</LinearLayout>
</LinearLayout>
and the call to rotate the view:
occasionsIncluder = (LinearLayout) findViewById(R.id.occasionIncluder);
occasionsIncluder.setRotation(rotateToValue);
rotateToValue is a simple call to the screen orientation value in degrees.
my question is why would disabling hardware overlays cause it to actually work better, i thought this option was to make things run smoother anyway?
Q: why would disabling hardware overlays cause it to actually work better?
A: I want to direct you to the official android documentation on Hardware Acceleration.
It says:
Because of the increased resources required to enable hardware acceleration, your app will consume more RAM.
If your application uses only standard views and Drawables, turning it on globally should not cause any adverse drawing effects. However, because hardware acceleration is not supported for all of the 2D drawing operations, turning it on might affect some of your applications that use custom views or drawing calls. Problems usually manifest themselves as invisible elements, exceptions, orwrongly rendered pixels.
To remedy this, Android gives you the option to enable or disable hardware acceleration at the following levels:
Application
Activity
Window
View
Hope this helps you understand the cause.For more, you can read through the link.
setWillNotDraw() was the culprit
This is my .xml file where I have used two scrollview,in Input Edittext and onether in output TextView. What is wrong here...It is not working in android device.
Another problem is that when I turn my device it only shows the input text area. The output text area goes down.I want to see the half screen of input and half screen of output area.
How to fix it??
Thanks
<?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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="35dp"
android:orientation="horizontal" >
<Button
android:id="#+id/test"
android:layout_width="60dp"
android:layout_height="38dp"
android:text="#string/test" />
<Button
android:id="#+id/rdf"
android:layout_width="60dp"
android:layout_height="38dp"
android:text="#string/rdf" />
<Button
android:id="#+id/load"
android:layout_width="75dp"
android:layout_height="38dp"
android:text="#string/load" />
<Button
android:id="#+id/clear"
android:layout_width="60dp"
android:layout_height="38dp"
android:text="#string/clear" />
<Button
android:id="#+id/close"
android:layout_width="fill_parent"
android:layout_height="38dp"
android:text="#string/close" />
</LinearLayout>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText
android:id="#+id/input"
android:layout_width="0dp"
android:layout_height="175dp"
android:layout_weight="1"
android:background="#fff"
android:ems="10"
android:gravity="top|left"
android:textSize="14dp"
android:inputType="textMultiLine" >
<requestFocus />
</EditText>
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/run"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/run" />
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/output"
android:layout_width="match_parent"
android:layout_height="225dp"
android:background="#fff"
android:text="#string/output"
android:textColor="#1e90ff" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Try setting layout_weight=1 and layout_height=0dp for the two scroll views instead of their
contents.
What is wrong here...It is not working in android device.
That's pretty vague. What were your expectations? What isn't working? In other words, please be a little more specific.
However, based on the layout code given, here are some recommendations:
Avoid hardcoding the size of views. You cannot make assumptions about screen size with the large variety of screen sizes, densities and devices out there. Also, even if you're able to make the layout look nice in portrait mode, it'll probably be not even close to that in landscape.
If you're going to put just a single View in a ScrollView, there's no need to wrap it in a ViewGroup container; just set the View directly, without nesting it again and added an extra layer of complexity to the view hierarchy.
There's no need to wrap a TextView or EditText with a ScrollView, as both views are scrollable by itself.
Regarding your second question: you can prevent Android from extracting all UI components when there's little layout estate left with the keyboard popped up. You'll need to set the IME_FLAG_NO_EXTRACT_UI flag on the EditText, or in xml: android:imeOptions="flagNoExtractUi".
I do like to point out that there's a reason Android has this behaviour by default. In most cases it hardly makes sense to force a tiny part of the UI to be visible, even more as whatever is being typed by the user is probably what really matters.
While developing an Android application I have stumbled upon a baffling problem. The UI element I am creating is a header bar that has a custom search field. Everything looks wonderful on the Android UI editor but the second I use the emulator or a device it bugs out and compresses the magnifying glass image and clips the edit text. I have tried a number of things including changing the background image of the search area to the custom search field that is currently in the parent LinearLayout. This however results in the search field size growing out of control.
Any suggestions are welcome.
My questions are:
1) How would one fix this problem while maintaining the look of the search area?
2) Why is this problem occurring?
Confirmed on the following devices:
Samsung Galaxy Nexus 4.0.2
Motorola Zoom 4.0.3
Nexus S 2.3.7
This is a screenshot of the UI editor:
This is a screenshot of what it looks like on all devices tested:
The XML used to generate these UI elements:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/title_bar_matte"
android:gravity="center_vertical"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_margin="10dp"
android:layout_weight="1.0"
android:background="#drawable/search_field"
android:gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="15dp"
android:src="#drawable/magnifying_glass" />
<EditText
android:id="#+id/campus_map_acitivity_search"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_weight="1.0"
android:background="#0FFF"
android:hint="Search"
android:imeOptions="actionSearch"
android:singleLine="true" />
</LinearLayout>
<Button
android:id="#+id/campus_map_activity_goto_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="#drawable/button_list" />
<Button
android:id="#+id/campus_map_activity_my_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="#drawable/button_location" />
</LinearLayout>
Just figured out the problem. The search background image had the top and left sides set to 9-patch scale. This is all good and well but we had forgotten to set the bottom and right fill areas so that the content would have room to exist.
http://radleymarx.com/blog/simple-guide-to-9-patch/
Remember to set the fill areas!
It turns out the Android UI editor does not handle 9-patch images like the devices. That seems to be a bug to me.