Set contentDescription for ActionBar's up button - android

I'm trying to customize the "Navigate up" default contentDescription that is associated with the up button of the ActionBar (I'm using ActionBarSherlock).
From ActionBarView's source:
public void setHomeButtonEnabled(boolean enable) {
mHomeLayout.setEnabled(enable);
mHomeLayout.setFocusable(enable);
// Make sure the home button has an accurate content description for accessibility.
if (!enable) {
mHomeLayout.setContentDescription(null);
} else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
mHomeLayout.setContentDescription(mContext.getResources().getText(
R.string.abs__action_bar_up_description));
} else {
mHomeLayout.setContentDescription(mContext.getResources().getText(
R.string.abs__action_bar_home_description));
}
}
so the key would be how to get a reference to mHomeLayout. getWindow().getDecorView().findViewById(android.R.id.home) is not working, as it's returning an ImageView.
How could I do?
Thanks ;)

layout
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/colorPrimary"
android:elevation="4dp"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
code
public Toolbar toolbar;
...
setContentView(layout);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(layoutTitle);
setSupportActionBar(toolbar);
...
getSupportActionBar().setHomeActionContentDescription("Go Back To XYZ Screen");

In xml, use "navigationContentDescription"
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_alignParentTop="true"
app:navigationContentDescription="#string/back"/>

Here how I can do what you need in a previous project :
((View) getWindow().getDecorView().findViewById(android.R.id.home).getParent().getParent()).setContentDescription("blablabla");
Using viewHierarchy plugin helps me to understand how ActionBar layout is build.

In case someone needs to set the ActionBar's home-button's content-description for UIAutomator, use
((View) getWindow().getDecorView().findViewById(android.R.id.home).getParent()).setContentDescription("MANUALLYSET-home-up");
and access the view in your UIAutomatorTestCase using
new UiObject(new UiSelector().description("MANUALLYSET-home-up").className("android.widget.FrameLayout"));
For some reason the additional *.getParent() did not work, instead Android uses some auto-generated content-description value for that parent which may differ in some Android versions (e.g. "app_name, Close navigation drawer" on KITKAT and "app_name, Navigate up" on JELLYBEAN). Accessing its child works too, fortunately.
Kind regards

Related

iOS equivalent for Android's include control

I am designing an cross-platform app for iOS aswell Android with a shared logic using MVVMCross (5.1.1).
Throughout my app I have a fixed toolbar at the top displaying the current view's title aswell a button. Below the bar the interface is changing from view to view
The Android part:
On Android I created a reuseable layout which I embed in my current layout using include.
In my portable project I have a BaseViewModel which has the properties the reuseable toolbar layout binds to. Every other ViewModel derives from this base class. This way I can have all bindable properties of a displayed screen in one ViewModel without the need of nesting but see for yourself:
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar_login" />
<RelativeLayout
android:id="#+id/parentLoginLayout"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/toolbar">
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
app:MvxBind="Text Pin"
/>
</RelativeLayout>
</RelativeLayout>
toolbar_login.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar_login"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="0dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:minWidth="25px"
android:minHeight="25px">
<TextView
app:MvxBind="Click ToolbarMenuCommand"
/>
<!-- some other -->
</android.support.v7.widget.Toolbar>
ViewModels.cs
using System.Threading.Tasks;
using Mobile.Helpers;
using ViewModels.Base;
using MvvmCross.Core.Navigation;
using MvvmCross.Core.ViewModels;
using Plugin.MessageBox;
namespace Mobile.ViewModels
{
public abstract class BaseViewModel : MvxViewModel
{
protected void NavigateToMainView()
{
NavigateTo<MainViewModel>();
}
private readonly IMvxNavigationService _navigationService;
protected BaseViewModel(IMvxNavigationService navigationService)
{
_navigationService = navigationService;
}
public IMvxCommand ToolbarMenuCommand => new MvxCommand(OnMenuButtonClick);
protected abstract void OnMenuButtonClick();
}
public class LoginViewModel : BaseViewModel
{
private bool _menuVisibility;
private string _pin;
public LoginViewModel(IMvxNavigationService navigationService) : base(navigationService)
{
}
public bool MenuVisibility
{
get => _menuVisibility;
set => SetProperty(ref _menuVisibility, value);
}
public string Pin
{
get => _pin;
set => SetProperty(ref _pin, value);
}
protected override void OnMenuButtonClick()
{
MenuVisibility = !MenuVisibility;
}
}
}
The iOS part:
I am not entirely sure how to realise above behavior on iOS. I hope someone has a good idea or a good example project for me which I can take a look at. In general it is no problem to refactorise the ViewModels incase my idea is just not possible at iOS.
A few facts about the iOS project:
I am not using storyboards but single .xib's being independent
from each other
In my .xib's files I use autolayout constraints for positioning and
sizing entirely
A few ideas I already had (cant test them right now):
1. idea:
Create a base .xib with the above bar, the constraints aswell the
outlets
Create each new xib Design based on the previously created file
This would mean I need to adjust every view incase I decide to change something about the toolbar but so far I found no other way to embed a .xib in another .xib without having two different ViewControllers. Also I read that inheritance cause problems with outlets.
2. idea
Each .xib has an empty view at the top which acts as a container for
the toolbar
Have a Base ViewController which constructs the toolbar from code and
adds it as a child to the container view, and binds the properties
from the BaseViewModel
In a previous iOS project I noticed that adding views to the layout can cause problems with autolayout. Probably also a not that good solution?
3. idea
Create a xib with the toolbar and a container below and use it as a master page which would probably mean having a MasterViewModel with the toolbar properties and a nested ChildViewModel.
This is probably the way to go but I have to admit that I have no clue what is the best way to approach it (stil pretty new to iOS and MVVMCross).
Does someone have a few useful hints for me? Thanks a lot!
From what I understood I think you should try to use ScrollView for iOS part and try to imitate the ViewPager's behavior from Android, an example.

Snackbar and other animations stopped working on some Android devices

I have a very odd issue that I cannot figure out. I was not an issue until recently but I can't seem to revert back to prevent it. Also the other odd thing is it works on some devices and others it does not.
The issue is animations. One in particular is snack bar. The snackbar should animate up and down but it is not. it just shows then hides. check video below to see issue.
Video of issue
Here is the Android code to animate the snackbar in
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
ViewCompat.setTranslationY(mView, mView.getHeight());
ViewCompat.animate(mView)
.translationY(0f)
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
.setDuration(ANIMATION_DURATION)
.setListener(new ViewPropertyAnimatorListenerAdapter() {
#Override
public void onAnimationStart(View view) {
mView.animateChildrenIn(ANIMATION_DURATION - ANIMATION_FADE_DURATION,
ANIMATION_FADE_DURATION);
}
#Override
public void onAnimationEnd(View view) {
onViewShown();
}
}).start();
}
Its using ViewCompat for the v4 Library. I have other animations working in another activity working fine. Also the issue is not on just one activity its all of them. That makes me think its system wide somehow. But they all use different internal themes but all extend Theme.AppCompat.NoActionBar.
Here is my main layout
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:elevation="4dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextAppearance="#style/ToolbarTitle"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextAppearance="#style/TabText"
app:tabMinWidth="#dimen/tab_minwidth"
app:tabMode="fixed"
app:tabGravity="fill"
app:layout_scrollFlags="enterAlways"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<fr.castorflex.android.circularprogressbar.CircularProgressBar
android:id="#+id/base_progressSpinner"
android:layout_gravity="center"
android:layout_width="48dp"
android:layout_height="48dp"
android:indeterminate="true"
android:visibility="invisible"
app:cpb_color="#color/spinner"
app:cpb_rotation_speed="1.0"
app:cpb_sweep_speed="1.0"
app:cpb_stroke_width="4dp"
app:cpb_min_sweep_angle="10"
app:cpb_max_sweep_angle="300"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_upload"
android:visibility="gone"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_anchor="#id/content_frame"
app:layout_anchorGravity="bottom|right|end"
app:borderWidth="0dp"
android:src="#drawable/app_fab_upload"
android:layout_margin="#dimen/big_padding"
android:clickable="true"
app:backgroundTint="#color/fab_social"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_muzei"
android:visibility="gone"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_anchor="#id/content_frame"
app:layout_anchorGravity="bottom|right|end"
app:borderWidth="0dp"
android:src="#drawable/app_fab_muzei"
android:layout_margin="#dimen/big_padding"
android:clickable="true"
app:backgroundTint="#color/fab_social"/>
</android.support.design.widget.CoordinatorLayout>
Devices it works on
Nexus 9 (Marshmallow)
Nexus 4 (KitKat)
Galaxy S7 (Marshmallow)
Devices it does not work
Droid Turbo 2 (Marshmallow)
Galaxy S7 (Marshmallow) *my device works, my testers does not
Nexus 6p (Android N)
The other animation issues are with Switches. I have 2 in same layout and one stutters when switched and the other just switches with no animation.
I also have a LayoutTransition set to my AppBarLayout to animation the hiding/showing of my TabLayout and it works fine and all devices
I found the reason why this is happening, but not how to fix yet.
/**
* Returns true if we should animate the Snackbar view in/out.
*/
private boolean shouldAnimate() {
return !mAccessibilityManager.isEnabled();
}
That is called by Snackbar class and is false on working devices, and true on devices not working. Does anyone know about this?
So after i disabled lastpass in my system settings, accessibility the snackbar now animates as it should. That is crazy how that works. Nova launcher has the same affect. I guess any service in accessibility that is enabled will cause the snackbar animation to not work.
As Bignadad mentioned, the problem is that any accessibility feature, including things like password managers, disables the snackbar animations. Google, as of this edit, has fixed this for AndroidX but not the Design support library
Because Snackbar's base class, BaseTransientBottomBar, handles the animation, with package private, final methods, you have two choices if you want to fix it: roll your own snackbar from scratch, or use a more hacky solution with reflection:
Kotlin example:
// Only force when necessary, and don't animate when TalkBack or similar services are enabled
val shouldForceAnimate = !accessibilityManager.isEnabled && accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN).isEmpty()
Snackbar.make(coordinatorLayout, text, duration).apply {
if (shouldForceAnimate) {
try {
val accManagerField = BaseTransientBottomBar::class.java.getDeclaredField("mAccessibilityManager")
accManagerField.isAccessible = true
val accManager = accManagerField.get(this)
AccessibilityManager::class.java.getDeclaredField("mIsEnabled").apply {
isAccessible = true
setBoolean(accManager, false)
}
accManagerField.set(this, accManager)
} catch (e: Exception) {
Log.d("Snackbar", "Reflection error: $e")
}
}
}.show()
Java example:
// Only force when necessary, and don't animate when TalkBack or similar services are enabled
boolean shouldForceAnimate = !accessibilityManager.isEnabled() && accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN).size == 0;
Snackbar snackbar = Snackbar.make(coordinatorLayout, text, duration);
if(shouldForceAnimate){
try {
Field accManagerField = BaseTransientBottomBar.class.getDeclaredField("mAccessibilityManager");
accManagerField.setAccessible(true);
AccessibilityManager accManager = (AccessibilityManager) accManagerField.get(snackbar);
Field isEnabledField = AccessibilityManager.class.getDeclaredField("mIsEnabled");
isEnabledField.setAccessible(true);
isEnabledField.setBoolean(accManager, false);
accManagerField.set(snackbar, accManager);
} catch (Exception e) {
Log.d("Snackbar", "Reflection error: " + e.toString());
}
}
snackbar.show();
I'd love a third option here, but I'm not aware of one, at least until AndroidX gets out of beta with the proper fix.
This has been fixed since Material Components for Android 1.0.0-alpha3 with this commit.
Use it instead of the Design Library (which is the way to go if you're using AndroidX):
implementation "com.google.android.material:material:$material_components_version"

NavigationView onClick from xml causes errors

Using NavigationView from the newly released Android support design library, if a navigation header layout includes an onClick (in the xml), onClick event crashes app. OnClick can be added programmatically via view.onClickListener (instead of xml), and then clicking works fine. But for some reason, whenever xml onClick is used, there is an error.
Here's my main layout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/mainActivityLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<RelativeLayout
android:id="#+id/mainContentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/drawerNavView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer_menu">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
In my activity, my menu item clicks (added with navView.setNavigationItemSelectedListener()) work fine. The problem is when the header is clicked:
drawer_header.xml:
...
<View
android:id="#+id/testButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:onClick="testButtonClick"/>
...
Produces the following error:
java.lang.IllegalStateException: Could not find a method testButtonClick(View)
in the activity class android.view.ContextThemeWrapper for onClick handler
on view class android.view.View with id 'testButton'
UPDATE
NavigationView can use standard Menu resource files, but there is a similar problem if using onClick from the menu XML resource. According to the Menu Resource reference, the android:onClick attribute overrides the normal callbacks. This usually works fine, but with menu items in NavigationView, it doesn't. Instead, it crashes with this error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{...}:
android.view.InflateException: Binary XML file line #34:
Error inflating class android.support.design.widget.NavigationView
The error goes away when I remove the XML onClick.
UPDATE
I tested xml onClick using the "official" demo project for the Android Design Library. Same results: adding onClick (in xml) to a NavigationView's menu or header causes the app the crash. So this appears to be a bug with NavigationView.
RESOLVED IN v23.1
Google released a fix for these XML onClick errors in Support Library v23.1.
Confirmed, this is a bug in the support library.
Apparently it's related to ContextThemeWrapper, and according to this bug report, the problem exists in Support Library 22.1.
So, the short answer is:
Don't use XML onClick with NavigationView (or some other components like EditText), until it's fixed.
Workaround:
Set click listeners in code. For NavigationView, use setNavigationItemSelectedListener().
UPDATE: This bug has ben fixed
You can now use XML onClick in Support Library 23.1 (bug report). I've verified it works in my app. But there seems to be other (newer) XML issues with NavView in v23.1 (see below), even though this particular onClick error is now fixed.
For completeness:
There appears to be another (related?) bug when inflating NavigationView header via XML. Using XML app:headerLayout produces errors with 23.1, even though XML onClick now works. Because of this inflation issue, you'll need to use NavigationView.inflateHeaderView() method in code. This new method was added in 23.1 and, apparently, the previous XML inflate is now broken (or maybe they deprecated app:headerLayout without telling anyone?). More info detailed here.
Hi: my solution is remove
app:headerLayout="#layout/drawer_header"
from your NavigationView layout as below:
<android.support.design.widget.NavigationView
android:id="#+id/drawerNavView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_menu">
</android.support.design.widget.NavigationView>
And then use below in your activity or view controller
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
View headerView= navigationView.inflateHeaderView(R.layout.nav_header);
TextView tvName = (TextView) headerView.findViewById(R.id.id_nav_header_uname);
tvName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
L.d("=======tv click=====");
}
});
this works for me.
You may write your method in code without mentioning it in XML. In code you just use the code
public void methodName()
{
//
}
View v = findViewById(R.id.view_id);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
methodName();
}
});
NavigationView has an OnNavigationItemSelectedListener for the Menu Items.
e.g.
navigationView.setNavigationItemSelectedListener(new SelectedNavigationItemListener());
private class SelectedNavigationItemListener implements NavigationView.OnNavigationItemSelectedListener {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()){
case id1:
break;
}
Log.d("MENU ITEM", menuItem.getTitle().toString());
return false;
}
}
For the Header you can do something like this e.g
navigationView = (NavigationView) findViewById(R.id.navigation_view);
View header = navigationView.inflateHeaderView(R.layout.drawer_header);
RelativeLayout drawerHeader = (RelativeLayout) header.findViewById(R.id.drawerHeader);
drawerHeader.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("CLICKED HEADER", "Header Clicked");
}
});
Reference for my HeaderLayout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textSize="16sp" />

TextInputLayout disable animation

I am using the TextInputLayout to implement the floating label pattern. However, when I set the text programmatically on the EditText, I still get the animation of the label moving from the control to the label - the same as if the user had clicked it.
I don't want this animation though if I set it programmatically, is this possible? Here is my code:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/root">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText1" />
</android.support.design.widget.TextInputLayout>
And in the onResume I do:
TextInputLayout root = (TextInputLayout)findViewById(R.id.root);
EditText et = (EditText)root.findViewById(R.id.editText1);
et.setText("Actual text");
root.setHint("Hint");
As of v23 of the support libs, a setHintAnimationEnabled method has been added. Here are the docs. So you can set this new attribute to false in the XML and then programmatically set it to true after you've finished populating the editText. OR simply handle it all programmatically, as needed.
So in your example, that would become something like:
TextInputLayout root = (TextInputLayout)findViewById(R.id.root);
root.setHintAnimationEnabled(false);
root.setHint("Hint");
EditText et = (EditText)root.findViewById(R.id.editText1);
et.setText("Actual text");
// later...
root.setHintAnimationEnabled(true);
Of course, be sure to open your Android SDK Manager and update your Android Support Library to rev. 23 and Android Support Repository to rev. 17 first and then add that to build.gradle via:
compile 'com.android.support:design:23.0.0'
Note that as the Design library depends on the Support v4 and AppCompat Support Libraries, those will be included automatically when you add the Design library dependency.
Put this attribute app:hintEnabled="false" here:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintEnabled="false">
It works for me
I have found an (unwieldy) way to do that. Looking into the source code of the TextInputLayout, I've discovered that the only occasion when the class doesn't update it's hint with animation is when the EditText is added to it. The only obstacle is that you can only add it once to the layout, once it is there, it will permanently be tied to it, and there's no way to remove it.
So here's the solution:
Create a TextInputLayout without the EditText. Programmatically or via XML inflation - doesn't matter, but it has to be empty.
Create the EditText and set its text to whatever you need.
Add the EditText to the TextInputLayout.
Here's an example:
TextInputLayout hintView = (TextInputLayout) findViewById(R.id.hint_view);
hintView.setHint(R.string.hint);
EditText fieldView = new EditText(hintView.getContext());
fieldView.setText(value);
hintView.addView(fieldView);
Unfortunately, if you want to set the text to something else without the animation, you will have to repeat all these steps, except for the creation of a new EditText (the last one can be reused). I hope Google can fix this, because it is really inconvenient, but for now that's what we have.
Update: this is, thankfully, fixed in the design library 23.0.0, so just update to that version, and you won't have to do all this crazy stuff.
You can disable it by using
app:hintAnimationEnabled="false"
I will give you simple code and you don't have to make all programmatically just add xlm attribute and that's all.
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintAnimationEnabled="true"
app:passwordToggleEnabled="true">
<EditText
android:id="#+id/password_field_activity_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:hint="#string/password"
android:inputType="textPassword"
android:padding="10dp"
android:textColor="#color/color_holo_light_gray"
android:textColorHint="#color/color_holo_light_gray"
android:textCursorDrawable="#drawable/cursor_drawable" />
</android.support.design.widget.TextInputLayout>
Hope it will help
I wrote a small method to run after loading the view hierarchy that disables animation on initial display but enables it after wards. Add this to your Base Activity/Fragment/View and it will solve it issue.
private void setTextInputLayoutAnimation(View view) {
if (view instanceof TextInputLayout) {
TextInputLayout til = (TextInputLayout) view;
til.setHintAnimationEnabled(false);
til.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override public boolean onPreDraw() {
til.getViewTreeObserver().removeOnPreDrawListener(this);
til.setHintAnimationEnabled(true);
return false;
}
});
return;
}
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
for (int i = 0; i < group.getChildCount(); i++) {
View child = group.getChildAt(i);
setTextInputLayoutAnimation(child);
}
}
}
I check out ideas about support library v23 - it's does not work yet :( Programmatically inserting of EditText is unusable if you wish to use databinding labrary
In result of research I found solution without full disabling of animation:
layout.xml
<android.support.design.widget.TextInputLayout
android:id="#+id/text_til"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/product_title_placeholder">
<android.support.design.widget.TextInputEditText
android:id="#+id/text_tiet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#={bindingText}"/>
</android.support.design.widget.TextInputLayout>
Activity.java
final TextInputLayout textLayout = (TextInputLayout) findViewById(R.id.text_til);
if(binding.getText() != null) {
// disable animation
textLayout.setHintAnimationEnabled(false);
final TextInputEditText editText = (TextInputEditText) titleLayout.findViewById(R.id.text_tiet);
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
// enable animation after layout inflated
textLayout.setHintAnimationEnabled(true);
editText.setOnFocusChangeListener(null);
}
});
}
// manage focus for new binding object
((View)textLayout .getParent()).setFocusableInTouchMode(binding.getText() == null);
It's looks not prettily, but it works :)

Does Android Have MasterPage Concept like .NET or Tiles concept in Struts to add Header on all pages?

I am developing an Android Application. In this application, Logo bar is shown on all pages(Activities) or we can say it has header on all pages.
This Logo Bar have few icons like Home, Login, Notification, etc. and on Clicking on these icons corresponding navigation will perform.
for example if user is any where in application and click on home icon, he will navigate to the home page of application.
I am able to inflate logobar.XML into my All Activity by coding. but problem is i have to call onClickListener on all pages for all icons in Logo Bar.
This is not a good programming way.
How can i implement Logo Bar Activity in all other activity without repeating of code?
Is android have any Master Page concept as in .Net or tiles concept as in Struts?
Please guide me.
Edit: ok i got it. may be this answer will help you.
Try using Tab widget with tabactivity check this link for using fragment and tab http://developer.android.com/reference/android/app/TabActivity.html for android. i think for lower versions also we can use this. this si what the link says - "you can use the v4 support library which provides a version of the Fragment API that is compatible down to DONUT."
you have to create your masterLayout in xml and that you have to include it in your other
layouts in which you have to have it.
The solution was pretty easy.
You need to extends "Activity" Class,in onCreate function SetContentView to your base xml layout and also need to override setContentView in base Activity Class
For Example:
1.Create "base_layout.xml" with the below code
<?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"
android:background="#000000"
android:padding="15dp" >
<LinearLayout android:orientation="horizontal" android:background="#000000"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:minHeight="50dp" android:paddingLeft="10dp">
<ImageView android:layout_width="wrap_content" android:id="#+id/ImageView01"
android:adjustViewBounds="true" android:layout_height="wrap_content"
android:scaleType="fitCenter" android:maxHeight="50dp" />
</LinearLayout>
<LinearLayout android:id="#+id/linBase"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</LinearLayout>
</LinearLayout>
2.Create "BaseActivity.java"
public class BaseActivity extends Activity {
ImageView image;
LinearLayout linBase;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.base_layout);
image = (ImageView)findViewById(R.id.ImageView01);
image.setImageResource(R.drawable.header);
linBase = (LinearLayout)findViewById(R.id.linBase);
}
#Override
public void setContentView(int id) {
LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(id, linBase);
}
}
and
public class SomeActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.some_layout);
//rest of code
}
}
The only thing I noticed so far was that when requesting a progress bar (requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) this needs to be done before calling super.onCreate. I think this is because nothing can be drawn yet before calling this function.
This worked great for me and hopefully you will find this useful in your own coding.
There is something like that, but only available on api 11+ (3.2 and Android 4.0.x Ice Cream Sandwich). Its called actionbar ( http://developer.android.com/reference/android/app/ActionBar.html).
I have done this using XML file.
I am just creating runtime view from XML file , and add it to the Activity layout.
I have created method for that
public static void setLoginview(Context ctx, RelativeLayout layout) {
LayoutInflater linflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View myView = linflater.inflate(R.layout.loginheader, null);
layout.addView(myView);
try {
layout.getChildAt(0).setPadding(0, 50, 0, 0);
} catch (Exception e) {
}
}
ctx is the application contetx and layout is the layout in which i want to add that view.

Categories

Resources