How to disable BottomNavigationView click and Touch? - android

i want to implement behavior on certain condition the bottom view is unable to click, i want to make if bottom view item being click it does not navigate to that item but still stay at the current item

You can disable menu items if you want to disable bottom navigation view
private void enableBottomBar(boolean enable){
for (int i = 0; i < mBottomMenu.getMenu().size(); i++) {
mBottomMenu.getMenu().getItem(i).setEnabled(enable);
}
}

Kotlin style one-liner:
bottom_navigation.menu.forEach { it.isEnabled = false }

<android.support.design.widget.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:contextClickable="false"/>
Try this code.it Disables the click.
Dynamicaly using Java pr Kotlin you can disable click.
bottomView.setEnabled(false);
bottomView.setFocusable(false);
bottomView.setFocusableInTouchMode(false);
bottomView.setClickable(false);
bottomView.setContextClickable(false);
bottomView.setOnClickListener(null);
setting onClick Listener to Null helps to Disable click events
bottomView.menu.forEach { it.isEnabled = false }

You can set the touch listeners of its subviews. Example using android-ktx:
bottomNav.children.forEach {
(it as? ViewGroup)?.children?.forEach {
it.setOnTouchListener { _, _ -> true } // or null to enable touch again
}
}

public class CustomBottomNavigationView extends BottomNavigationView {
...
#Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
ViewGroup menuView = (ViewGroup) getChildAt(0);
if (menuView != null) {
for (int i = 0; i < menuView.getChildCount(); i++) {
menuView.getChildAt(i).setEnabled(enabled);
}
}
}
}

You can do something like
bottomNavigation.menu.iterator().forEach { it.isEnabled = !error }

Related

How to make a group of views editable

I have a layout in which there are spinners, editText and checkboxes. There two modes:
1- edit all views (edit mode)
2- view (non edit mode)
But I don't want to do it for each view . Is there any way to set editable true or false?
This method will enable/disable all widgets of your parent layout.
public void enableAllView(ViewGroup rootView, boolean state) {
for (int i = 0; i < rootView.getChildCount(); i++) {
View childAt = rootView.getChildAt(i);
if (childAt instanceof ViewGroup ) {
enableAllView((ViewGroup) childAt, state);
} else {
if (childAt instanceof EditText) {
EditText child = (EditText) childAt;
child.setEnabled(state);
child.setFocusable(state);
} else if (childAt instanceof Spinner) {
Spinner child = (Spinner) childAt;
child.setEnabled(state);
child.setFocusable(state);
} else if (childAt instanceof CheckBox) {
CheckBox child = (CheckBox) childAt;
child.setEnabled(state);
child.setFocusable(state);
}
}
}
}
call this method like this--
enableAllView(rootView, true); // in case of edit(enable)
enableAllView(rootView, false); // in case of view(disable)
//rootView is a view in which your spinners/editText/checkbox are availabe.
in edit mode use this in every view
yourView.setEnabled(true);
in read mode use this
yourView.setEnabled(false);
The simple way is to create a set of such views manually:
val editableViews: Set<View> = setOf(v1, v2, v3)
and use it:
editableViews.forEach { it.enabled = isEditMode }
If you have a complex layout you may add dynamic initialization:
private fun getAllViews(
view: View,
set: MutableSet<View>,
filter: (view: View) -> Boolean = {true}
){
val viewGroup = view as? ViewGroup
if (viewGroup != null) {
for (i: Int in 0 until viewGroup.childCount) {
val child = viewGroup.getChildAt(i)
getAllViews(child, set)
}
} else {
if (filter()) {
set.add(view)
}
}
}
initialize it in onViewCreated or in onCreate
val views = mutableSetOf<View>()
getAllViews(root, views) {
it is Spinner || it is EditText || it is Checkbox
}
editableViews = views
It collects all required views, so you may make them enabled or disabled. But you should note, that this variant is not so flexible and you should prefer just the first one. (In case any exception you have to exclude some)

Visible password with TextInputLayouts passwordToggleEnabled

I am using a TextInputLayout with the new function from the Support Library: passwordToggleEnabled. This gives a nice "eye"-icon that lets the user toggle password visibility on and off.
My question is if there is a way to use this functionality but start with password visible?
My xml:
<android.support.design.widget.TextInputLayout
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true">
<EditText
android:id="#+id/password_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/prompt_password"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
The toggle looks similar to this:
I have not found a way to do this in xml, and not a way to manually toggle the visibility after the view is rendered. If I set the input type of the EditText to textVisiblePassword, the toggle is not shown. If I do it in code using for instance mPasswordEditText.setTransformationMethod(null); the password is shown but the toggle is gone and the user can't hide the password again. I know I can do it all manually but just wondering if I can make it work with the new magic toggle
Easiest way is below Another solution is at last of this answer
private void setupPasswordToggleView() {
final TextInputLayout textInputLayout = mRootView.findViewById(R.id.password);
// You can skip post-call and write directly the code which is inside run method.
// But to be safe (as toggle-view is child of TextInputLayout, post call
// has been added.
textInputLayout.post(new Runnable() {
#Override
public void run() {
CheckableImageButton passwordToggleView = textInputLayout.findViewById(R.id.text_input_password_toggle);
// passwordToggleView.toggle(); // Can not use as restricted to use same library group
// passwordToggleView.setChecked(true); // Can not use as restricted to use same library group
passwordToggleView.performClick();
}
});
}
Now let me explain the answer
While looking into code of TextInputLayout.java I found that, there is a layout design_text_input_password_icon.xml which is being added to TextInputLayout.java. Below is that code
private void updatePasswordToggleView() {
if (mEditText == null) {
// If there is no EditText, there is nothing to update
return;
}
if (shouldShowPasswordIcon()) {
if (mPasswordToggleView == null) {
mPasswordToggleView = (CheckableImageButton) LayoutInflater.from(getContext())
.inflate(R.layout.design_text_input_password_icon, mInputFrame, false);
mPasswordToggleView.setImageDrawable(mPasswordToggleDrawable);
mPasswordToggleView.setContentDescription(mPasswordToggleContentDesc);
mInputFrame.addView(mPasswordToggleView); // << HERE IS THAT
.........
}
Now next target was to find design_text_input_password_icon.xml and lookup id of the toggle view. So found the layout design_text_input_password_icon.xml here and it has written as
18<android.support.design.widget.CheckableImageButton
19 xmlns:android="http://schemas.android.com/apk/res/android"
20 android:id="#+id/text_input_password_toggle"
21 android:layout_width="wrap_content"
22 android:layout_height="wrap_content"
23 android:layout_gravity="center_vertical|end|right"
24 android:background="?attr/selectableItemBackgroundBorderless"
25 android:minHeight="48dp"
26 android:minWidth="48dp"/>
I found the id text_input_password_toggle of that view and now everything was easy to just find that view in it's viewgroup and perform action on that.
Another solution would be to iterate childs of TextInputLayout and check if it is CheckableImageButton and then perform click on it. By this way there would not be dependancy on id of that view and if Android changes the id of view, our solution will still work. (Although they do not change id of a view in normal cases).
private void setupPasswordToggleViewMethod2() {
final TextInputLayout textInputLayout = mRootView.findViewById(R.id.password);
textInputLayout.post(new Runnable() {
#Override
public void run() {
View toggleView = findViewByClassReference(textInputLayout, CheckableImageButton.class);
if (toggleView != null) {
toggleView.performClick();
}
}
});
}
Where findViewByClassReference(View rootView, Class<T> clazz) original utility class is defined as below
public static <T extends View> T findViewByClassReference(View rootView, Class<T> clazz) {
if(clazz.isInstance(rootView)) {
return clazz.cast(rootView);
}
if(rootView instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) rootView;
for(int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
T match = findViewByClassReference(child, clazz);
if(match != null) {
return match;
}
}
}
return null;
}
With the Material Components Library (1.1.0 , 1.2.0-beta01, 1.3.0-alpha01) to start with a visible password just use:
<com.google.android.material.textfield.TextInputLayout
app:endIconMode="password_toggle"
/>
and in your code:
textInputLayout.getEditText().setTransformationMethod(null);
If you want to return to the default behavior:
textInputLayout.getEditText()
.setTransformationMethod(PasswordTransformationMethod.getInstance());
Just removing android:inputType="textPassword" worked for me
One of the ways is, we can search CheckableImageButton from TextInputLayout, and then programmatically perform onClick on it, based on the password visibility status of EditText.
Here's the code snippet.
private CheckableImageButton findCheckableImageButton(View view) {
if (view instanceof CheckableImageButton) {
return (CheckableImageButton)view;
}
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0, ei = viewGroup.getChildCount(); i < ei; i++) {
CheckableImageButton checkableImageButton = findCheckableImageButton(viewGroup.getChildAt(i));
if (checkableImageButton != null) {
return checkableImageButton;
}
}
}
return null;
}
//...
if (passwordEditText.getTransformationMethod() != null) {
CheckableImageButton checkableImageButton = findCheckableImageButton(passwordTextInputLayout);
if (checkableImageButton != null) {
// Make password visible.
checkableImageButton.performClick();
}
}
I was able to get it to start in clear-text mode with the following bit of code. Basically, I had to find the right View using the content description.
If they provided a setter method for mPasswordToggledVisibility that would make things a lot easier...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextInputLayout til = findViewById(R.id.password);
CharSequence cs = til.getPasswordVisibilityToggleContentDescription();
ArrayList<View> ov = new ArrayList<>();
til.findViewsWithText(ov, cs,View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if( ov.size() == 1 ) {
Checkable c = (Checkable)ov.get(0);
// As far as I can tell the check for "isChecked" here isn't needed,
// since it always starts unchecked by default. However, if you
// wanted to check for state, you could do it this way.
if( c != null && !c.isChecked()) {
ov.get(0).performClick();
}
}
}
try this
if (inputEditText.getTransformationMethod() == null) {
inputEditText.setTransformationMethod(new PasswordTransformationMethod());
} else {
inputEditText.setTransformationMethod(null);
}
inputEditText.setSelection(inputEditText.getText().length());
You can use the bellow code:
TextInputLayout yourTextInputLayoutId = findViewById(R.id.yourTextInputLayoutId);
FrameLayout frameLayout = (FrameLayout) (yourTextInputLayoutId).getChildAt(0);
CheckableImageButton checkableImageButton = (CheckableImageButton) frameLayout.getChildAt(1);
checkableImageButton.performClick();
Here yourTextInputLayoutId is your TextInputLayout id from xml.
To start with Password visible,
Do not include
android:inputType="textPassword"
In
<com.google.android.material.textfield.TextInputEditText>
....
</com.google.android.material.textfield.TextInputEditText>
You can add in your xml file in TextInputLayout
passwordToggleEnabled="true"
passwordToggleDrawable=""#drawable/show_password_selector"
and make your show_password_selector.xml
this will look the same as the picture you sent
You can use:
yourEditText.setTransformationMethod(new PasswordTransformationMethod());
To re-show the readable password, just pass null as transformation method:
yourEditText.setTransformationMethod(null);
so user can hide it again.

Android Studio GridLayout toggle all button

I'm using a Gridlayout with the MyView.java class. I got the code from GridLayout.
I implemented another button under the GridLayout. I want to toggle all (GrigLayout-)Buttons with this button. Does anyone have an Idea how I could do this?
Thank you!!!
You have to revise through all child views, and check if they are toggle buttons. Here is an example, when you want to toggle, call toggleButtons(grid);
private void toggleButtons(ViewGroup v) {
View a;
for(int i = 0; i < v.getChildCount(); i++)
{
a = v.getChildAt(i);
if(a instanceof ViewGroup) {
toggleButtons((ViewGroup) a);
}
else if(a instanceof Button){
// Toggle here
}
}
}

SearchView setOnClickListener NOT WORkING

Can anyone see why this is not working..
My SearchView is in the ActionBar and is always shown. I want to know when a user PRESSES the searchview... not when it expands or gains focus.
This code sits within onCreateOptionsMenu
SearchView = _searchView;
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
_searchView = (SearchView) menu.findItem(R.id.menu_finder_text_search).getActionView();
_searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
_searchView.setIconifiedByDefault(false); // Do not iconify the widget, we want to keep it open!
_searchView.setFocusable(false);
_searchView.setClickable(true);
_searchView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//DO SOMETHING!
}
});
Anyone?
SearchView is inherited from LinearLayout, so we can setOnClickListener for each child, like this:
public static void setSearchViewOnClickListener(View v, OnClickListener listener) {
if (v instanceof ViewGroup) {
ViewGroup group = (ViewGroup)v;
int count = group.getChildCount();
for (int i = 0; i < count; i++) {
View child = group.getChildAt(i);
if (child instanceof LinearLayout || child instanceof RelativeLayout) {
setSearchViewOnClickListener(child, listener);
}
if (child instanceof TextView) {
TextView text = (TextView)child;
text.setFocusable(false);
}
child.setOnClickListener(listener);
}
}
}
from: http://www.trinea.cn/android/searchview-setonclicklistener-not-working/
Ok, it does not answer the problem it only avoids it.
I have used this link to create a listener for when the keyboard is shown. This gives me an event at the right time for me.
https://stackoverflow.com/a/7423586/1312937
Try this:
1) Bind the view
#BindView(R.id.search) SearchView search;
2) In your onCreate(), write the following code.
search.setIconifiedByDefault(false);
search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
search.setIconified(false);
}
});
3) And your SearchView should have this following attributes.
<SearchView
android:id="#+id/search"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:background="#drawable/rounded_corners_box"
android:drawableLeft="#android:drawable/ic_menu_search"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:queryHint="Search your item.."
android:textColor="#android:color/black"
android:textColorHint="#color/colorPrimary"
app:defaultQueryHint="Select locality"/>
NOTE:
android:background="#drawable/rounded_corners_box" -- your custom border xml file.
android:drawableLeft="#android:drawable/ic_menu_search" -- search icon from drawable file.
Bind the Searchviews button to a custom ImageView and add the onClickListener there
ImageView searchButton = this.searchView.findViewById(android.support.v7.appcompat.R.id.search_button);
searchButton.setOnClickListener(v -> {
// Your code here
//This is needed since you are overwriting the default click behaviour
searchView.setIconified(false);
});
Recently stuck with this problem and found a simple solution.
searchView.setOnQueryTextFocusChangeListener(object : View.OnFocusChangeListener{
override fun onFocusChange(p0: View?, p1: Boolean) {
// Enter your code here
}
})
This method will be called when you will tap on search field and soft keyboard will appear.
Use the interface OnTouchListener: http://developer.android.com/reference/android/view/View.OnTouchListener.html
This requires a tiny bit more implementation code, but gives superior control over the UI. This solution assumes the user will be using a touch screen to interact with the View.
int search_button_id = context.getResources().getIdentifier("android:id/search_button", null, null);
ImageView search_button_view = (ImageView) mSearchView.findViewById(search_button_id);
search_button_view.setOnTouchListener((view, motionEvent) -> {
mSearchView.setIconified(false);
return true;
});

Set Default selection for GridView

Can anyone guide me how set particular element of grid view as selected ?
.setSelection(positionOfItem) is not working .
gridViewSize = (GridView) inflaterView.findViewById(R.id.grid_sizes);
gridViewSize.setAdapter(new PopupSizeAdapter(context,typeArr,1));
gridViewSize.setSelection(0);
it worked for me
mGridView.setSelection(pos);
mGridView.requestFocusFromTouch();
mGridView.setSelection(pos);
I came across the same issue today, following is my solution:
GridView.getViewTreeObserver.addOnGlobalLayoutListener(getLayoutListener(mGridView))
private static ViewTreeObserver.OnGlobalLayoutListener getLayoutListener(final GridView mGridView) {
ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
View view = mGridView.getChildAt(0);
if(view != null) {
if(!view.isSelected()) {
view.setSelected(true);
} else {
// remove the listener after the first time.
if (Build.VERSION.SDK_INT < 16) {
mGridView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mGridView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
}
}
};
return listener;
}
and also, if you are using android API >= 11, you can also add a View.OnLayoutChangeListener to GridView.
Try this:
grid.performItemClick(view, position, id);
Then my state drawable works correctly on GridView.

Categories

Resources