customize bottom navigation bar item layout - java

I want create following customized bottom navigation bar. How I can set custom layout for menu item? or is there exists ready library for creating this type bottom bar easily?

My code below work fine:
First, you need create a Bottom Navigation Activity template project in Android Studio and apply my code below:
button_custom.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="#drawable/button_border"
android:src="#drawable/ic_baseline_add_24"/>
</FrameLayout>
button_border.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp"/>
<solid android:color="#android:color/holo_blue_light"/>
</shape>
ic_baseline_add_24.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#android:color/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#android:color/white"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
</vector>
bottom_nav_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_home"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/title_home" />
<item
android:id="#+id/navigation_dashboard"
android:title="" />
<item
android:id="#+id/navigation_notifications"
android:icon="#drawable/ic_notifications_black_24dp"
android:title="#string/title_notifications" />
</menu>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" />
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
//Add custom tab menu
val bottomMenuView = navView.getChildAt(0) as BottomNavigationMenuView
val view = bottomMenuView.getChildAt(1)
val itemView = view as BottomNavigationItemView
val viewCustom = LayoutInflater.from(this).inflate(R.layout.button_custom, bottomMenuView, false)
itemView.addView(viewCustom)
}
}
My result:

This is just themed and the icon is set with: <item android:icon="#drawable/some_icon" ... />.
Requesting a library for such a simple task is a) questionable and b) also considered as off-topic.

Related

IDs to IDs linking on menus of drawer and toolbar to nav_graph not working

Please, I integrated the new Navigation Controller Component, using navHostFragment. My project runs on one activity-to-many fragments. It got a drawer & toolbar. I read that it is possible to set the ids in both menus (drawer, toolbar), to same ids in nav_graph for navigation when onClick event occurs.
activity_main.xml
<androidx.drawerlayout.widget.DrawerLayout 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"
xmlns:tools="http://schemas.android.com/tools"
android:background="#color/colorPrimary"
android:id="#+id/appContainer"
tools:context=".MainFragment"
tools:openDrawer="start"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/main_toolbar"
app:title="#string/app_name"
android:theme="#style/AppTheme.AppBarOverlay" />
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph"
android:transitionName="#string/transition_type_container" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemTextColor="#color/drawer_selector"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/menu_left_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
nav_graph.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_graph"
app:startDestination="#id/mainFragment">
<fragment
android:id="#+id/mainFragment"
android:name="com.emexrevolarter.worksmart.MainFragment"
android:label="fragment_holder"
tools:layout="#layout/fragment_holder" />
<fragment
android:id="#+id/aboutFragment"
android:name="com.emexrevolarter.worksmart.AboutFragment"
android:label="fragment_about"
tools:layout="#layout/fragment_about" />
<fragment
android:id="#+id/cameraFragment"
android:name="com.emexrevolarter.worksmart.CameraFragment"
android:label="fragment_camera"
tools:layout="#layout/fragment_camera" />
<fragment
android:id="#+id/accountFragment"
android:name="com.emexrevolarter.worksmart.AccountFragment"
android:label="fragment_account"
tools:layout="#layout/fragment_account" />
<fragment
android:id="#+id/formCreateAccountFragment"
android:name="com.emexrevolarter.worksmart.forms.FormCreateAccountFragment"
android:label="fragment_form_create_acount"
tools:layout="#layout/fragment_form_create_acount" />
<fragment
android:id="#+id/formUserLoginFragment"
android:name="com.emexrevolarter.worksmart.forms.FormUserLoginFragment"
android:label="fragment_form_user_login"
tools:layout="#layout/fragment_form_user_login" />
<fragment
android:id="#+id/helpFragment"
android:name="com.emexrevolarter.worksmart.HelpFragment"
android:label="fragment_help"
tools:layout="#layout/fragment_help" />
<activity
android:id="#+id/cameraXActivity"
android:name="com.emexrevolarter.worksmart.media.CameraXActivity"
android:label="activity_camera"
tools:layout="#layout/activity_camera" />
<fragment
android:id="#+id/placeholderFragment"
android:name="com.emexrevolarter.worksmart.ui.main.PlaceholderFragment"
android:label="fragment_main"
tools:layout="#layout/fragment_main" />
<activity
android:id="#+id/mainActivity"
android:name="com.emexrevolarter.worksmart.MainActivity"
android:label="MainActivity" />
<activity
android:id="#+id/splashActivity"
android:name="com.emexrevolarter.worksmart.SplashActivity"
android:label="splash_animation"
tools:layout="#layout/splash_animation" />
<navigation android:id="#+id/nested_settings"
app:startDestination="#id/settingsFragment">
<fragment
android:id="#+id/settingsFragment"
android:name="com.emexrevolarter.worksmart.SettingsFragment"
android:label="fragment_settings"
tools:layout="#layout/fragment_settings" />
<fragment
android:id="#+id/formEditAboutFragment"
android:name="com.emexrevolarter.worksmart.forms.FormEditAboutFragment"
android:label="fragment_form_edit_about"
tools:layout="#layout/fragment_form_edit_about" />
<fragment
android:id="#+id/listUsersFragment"
android:name="com.emexrevolarter.worksmart.view.ListUsersFragment"
android:label="fragment_list_users"
tools:layout="#layout/fragment_list_users" />
</navigation>
<navigation android:id="#+id/nested_tips"
app:startDestination="#id/searchFragment">
<fragment
android:id="#+id/searchFragment"
android:name="com.emexrevolarter.worksmart.SearchFragment"
android:label="fragment_search"
tools:layout="#layout/fragment_search" />
<fragment
android:id="#+id/tipsFragment"
android:name="com.emexrevolarter.worksmart.TipsFragment"
android:label="fragment_tips"
tools:layout="#layout/fragment_tips" />
</navigation>
<navigation android:id="#+id/nested_tasks"
app:startDestination="#id/tasksFragment">
<fragment
android:id="#+id/tasksFragment"
android:name="com.emexrevolarter.worksmart.TasksFragment"
android:label="fragment_tasks"
tools:layout="#layout/fragment_tasks" />
</navigation>
<navigation android:id="#+id/nested_notifications"
app:startDestination="#id/notificationsFragment">
<fragment
android:id="#+id/notificationsFragment"
android:name="com.emexrevolarter.worksmart.NotificationsFragment"
android:label="fragment_notifications"
tools:layout="#layout/fragment_notifications" />
</navigation>
<navigation android:id="#+id/nested_report"
app:startDestination="#id/reportFragment">
<fragment
android:id="#+id/reportFragment"
android:name="com.emexrevolarter.worksmart.ReportFragment"
android:label="fragment_report"
tools:layout="#layout/fragment_report" />
</navigation>
menu_left_drawer.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#android:color/white"
android:id="#+id/leftDrawer"
tools:viewBindingIgnore="true"
tools:context=".MainActivity">
<group
android:id="#+id/group1"
android:checkableBehavior="single">
<item android:id="#+id/aboutFragment"
android:title="#string/drawer_about"
android:icon="#drawable/ic_baseline_info_24"
android:iconTint="#color/colorPrimary" />
<item android:title="#string/drawer_label">
<menu>
<item android:id="#+id/helpFragment"
android:title="#string/drawer_help"
android:icon="#drawable/ic_baseline_help_24"
android:iconTint="#color/colorPrimary"/>
</menu>
</item>
</group>
main_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/notificationsFragment"
android:icon="#drawable/ic_baseline_notifications_24"
app:showAsAction="ifRoom"
android:visible="false"
android:title="Notification">
</item>
<item
android:id="#+id/searchFragment"
android:icon="#drawable/ic_baseline_search_24"
app:showAsAction="ifRoom"
android:visible="false"
android:title="Search">
</item>
<item
android:id="#+id/accountFragment"
android:icon="#drawable/ic_baseline_lock_open_24"
app:showAsAction="ifRoom|withText"
android:title="Account">
</item>
Everything works as per navigation if I use the below:
subText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// action_global_aboutFragment
NavController navController = Navigation.findNavController(v);
navController.navigate(R.id.nested_settings);
}
});
More Info:
minSdkVersion 23
targetSdkVersion 30
Implementation:
// Java language implementation
def nav_version = "2.3.3"
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
I need a solution to this, as regards IDs to IDs linking. I love the concept. Who got this working on Android Java?
Solved!
Listeners are needed for both Drawer & Toolbar
// setup click listeners for Drawer & Toolbar
drawerView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
int id = menuItem.getItemId();
if(id == R.id.accountFragment) {
// add your code here
} else {
NavigationUI.onNavDestinationSelected(menuItem, navController);
}
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
// drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
});
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// Handle Menu item selection
switch (item.getItemId()) {
case R.id.aboutFragment:
// add your code here
return true;
default:
// default function;
NavigationUI.onNavDestinationSelected(item, navController);
return true;
}
// return false;
}
});
Thank you.

can not working windowsoftinputmode in android [duplicate]

I would like to adjust/re-size the layout when the soft-keyboard activated, as below:
Before and After:
Found couple resources in SO:
How to keep all fields and texts visible while the soft keyboard is shown
android soft keyboard spoils layout when appears
Adjust layout when soft keyboard is on
But the questions & answers are rather ambiguous, here's the question with clearer picture of what I want.
Requirements:
It should work on phone with any screen sizes.
Noticed that the margin/padding space at "FACEBOOK" and "Sign Up for
Facebook" has changed before and after.
No scroll view is involved.
Just add
android:windowSoftInputMode="adjustResize"
in your AndroidManifest.xml where you declare this particular activity and this will adjust the layout resize option.
some source code below for layout design
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="FaceBook"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_marginTop="30dp"
android:ems="10"
android:hint="username" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/editText1"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="password" />
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/editText2"
android:layout_centerHorizontal="true"
android:layout_marginLeft="18dp"
android:layout_marginTop="20dp"
android:text="Log In" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="17dp"
android:gravity="center"
android:text="Sign up for facebook"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
This question has beeen asked a few years ago and "Secret Andro Geni" has a good base explanation and "tir38" also made a good attempt on the complete solution, but alas there is no complete solution posted here.
I've spend a couple of hours figuring out things and here is my complete solution with detailed explanation at the bottom:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/mainLayout"
android:layout_alignParentTop="true"
android:id="#+id/headerLayout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:text="facebook"
android:textStyle="bold"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:id="#+id/mainLayout"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText1"
android:ems="10"
android:hint="Email or Phone"
android:inputType="textVisiblePassword">
<requestFocus />
</EditText>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="#+id/editText2"
android:ems="10"
android:hint="Password"
android:inputType="textPassword" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="#+id/button1"
android:text="Log In"
android:onClick="login" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#+id/mainLayout"
android:id="#+id/footerLayout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView2"
android:text="Sign Up for Facebook"
android:layout_centerHorizontal="true"
android:layout_alignBottom="#+id/helpButton"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="#+id/helpButton"
android:text="\?"
android:onClick="help" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</ScrollView>
And in AndroidManifest.xml, don't forget to set:
android:windowSoftInputMode="adjustResize"
on the <activity> tag that you want such layout.
Thoughts:
I've realized that RelativeLayout are the layouts that span thru all available space and are then resized when the keyboard pops up.
And LinearLayout are layouts that don't get resized in the resizing process.
That's why you need to have 1 RelativeLayout immediately after ScrollView to span thru all available screen space. And you need to have a LinearLayout inside a RelativeLayout else your insides would get crushed when the resizing occurs. Good example is "headerLayout". If there wouldn't be a LinearLayout inside that RelativeLayout "facebook" text would get crushed and wouldn't be shown.
In the "facebook" login pictures posted in the question I've also noticed that the whole login part (mainLayout) is centered vertical in relation to the whole screen, hence the attribute:
android:layout_centerVertical="true"
on the LinearLayout layout. And because mainLayout is inside a LinearLayout this means that that part does't get resized (again see picture in question).
Add this line in your Manifest where your Activity is called
android:windowSoftInputMode="adjustPan|adjustResize"
or
you can add this line in your onCreate
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
It can work for all kind of layout.
add this to your activity tag in AndroidManifest.xml
android:windowSoftInputMode="adjustResize"
for example:
<activity android:name=".ActivityLogin"
android:screenOrientation="portrait"
android:theme="#style/AppThemeTransparent"
android:windowSoftInputMode="adjustResize"/>
add this on your layout tag in activitypage.xml that will change its position.
android:fitsSystemWindows="true"
and
android:layout_alignParentBottom="true"
for example:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:fitsSystemWindows="true">
Android Developer has the right answer, but the provided source code is pretty verbose and doesn't actually implement the pattern described in the diagram.
Here is a better template:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- stuff to scroll -->
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<!-- footer -->
</FrameLayout>
</RelativeLayout>
</ScrollView>
Its up to you to decide what views you use for the "scrolling" and "footer" parts. Also know that you probably have to set the ScrollViews
fillViewPort .
This makes it possible to show any wanted layout previously hidden by the keyboard.
Add this to the activity tag in AndroidManifest.xml
android:windowSoftInputMode="adjustResize"
Surround your root view with a ScrollView, preferably with scrollbars=none. The ScrollView will properly not change any thing with your layout except be used to solve this problem.
And then set fitsSystemWindows="true" on the view that you want to make fully shown above the keyboard.
This will make your EditText visible above the keyboard, and make it possible to scroll down to the parts below the EditText but in the view with fitsSystemWindows="true".
android:fitsSystemWindows="true"
For example:
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
...
</android.support.constraint.ConstraintLayout>
</ScrollView>
If you want to show the full part of fitsSystemWindows="true" view above the keyboard in the moment the keyboard appears, you will need some code to scroll the view to the bottom:
// Code is in Kotlin
setupKeyboardListener(scrollView) // call in OnCreate or similar
private fun setupKeyboardListener(view: View) {
view.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
view.getWindowVisibleDisplayFrame(r)
if (Math.abs(view.rootView.height - (r.bottom - r.top)) > 100) { // if more than 100 pixels, its probably a keyboard...
onKeyboardShow()
}
}
}
private fun onKeyboardShow() {
scrollView.scrollToBottomWithoutFocusChange()
}
fun ScrollView.scrollToBottomWithoutFocusChange() { // Kotlin extension to scrollView
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY + height)
smoothScrollBy(0, delta)
}
Full layout example:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<RelativeLayout
android:id="#+id/statisticsLayout"
android:layout_width="match_parent"
android:layout_height="340dp"
android:background="#drawable/some"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/logoImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:src="#drawable/some"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/authenticationLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:layout_marginTop="20dp"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/statisticsLayout">
<android.support.design.widget.TextInputLayout
android:id="#+id/usernameEditTextInputLayout"
android:layout_width="match_parent"
android:layout_height="68dp">
<EditText
android:id="#+id/usernameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/passwordEditTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/usernameEditTextInputLayout">
<EditText
android:id="#+id/passwordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/passwordEditTextInputLayout"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:layout_marginTop="20dp" />
<Button
android:id="#+id/forgotPasswordButton"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_below="#id/loginButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
For those using ConstraintLayout, android:windowSoftInputMode="adjustPan|adjustResize" will not work.
What you can do is use a soft keyboard listener, set constraints of the views from bottom to bottom of the upper views, then set a vertical bias for each view (as a positional percentage between constraints) to a horizontal guideline (also positioned by percentage, but to the parent).
For each view, we just need to change app:layout_constraintBottom_toBottomOf to #+id/guideline when the keyboard is shown, programmatically of course.
<ImageView
android:id="#+id/loginLogo"
...
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.15" />
<RelativeLayout
android:id="#+id/loginFields"
...
app:layout_constraintVertical_bias=".15"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/loginLogo">
<Button
android:id="#+id/login_btn"
...
app:layout_constraintVertical_bias=".25"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/loginFields"/>
Generally a soft keyboard takes up no more than 50% of the height of the screen. Thus, you can set the guideline at 0.5.
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"/>
Now programmatically, when the keyboard is not shown, we can set all the app:layout_constraintBottom_toBottomOf back to parent, vice-versa.
unregistrar = KeyboardVisibilityEvent.registerEventListener(this, isOpen -> {
loginLayout.startAnimation(AnimationManager.getFade(200));
if (isOpen) {
setSoftKeyViewParams(loginLogo, R.id.guideline, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
63, 0, 63, 0);
setSoftKeyViewParams(loginFields, R.id.guideline, -1, R.id.loginLogo, null, 0.15f,
32, 0, 32, 0);
setSoftKeyViewParams(loginBtn, R.id.guideline, -1, R.id.useFingerPrintIdText, null, 0.5f,
32, 0, 32, 0);
} else {
setSoftKeyViewParams(loginLogo, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
63, 0, 63, 0);
setSoftKeyViewParams(loginFields, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.loginLogo,null, 0.15f,
32, 0, 32, 0);
setSoftKeyViewParams(loginBtn, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.useFingerPrintIdText,null, 0.25f,
32, 0, 32, 0);
}
});
Call this method:
private void setSoftKeyViewParams(View view, int bottomToBottom, int topToTop, int topToBottom, String ratio, float verticalBias,
int left, int top, int right, int bottom) {
ConstraintLayout.LayoutParams viewParams = new ConstraintLayout.LayoutParams(view.getLayoutParams().width, view.getLayoutParams().height);
viewParams.dimensionRatio = ratio;
viewParams.bottomToBottom = bottomToBottom;
viewParams.topToTop = topToTop;
viewParams.topToBottom = topToBottom;
viewParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
viewParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
viewParams.verticalBias = verticalBias;
viewParams.setMargins(Dimensions.dpToPx(left), Dimensions.dpToPx(top), Dimensions.dpToPx(right), Dimensions.dpToPx(bottom));
view.setLayoutParams(viewParams);
}
The important thing is to be sure to set the vertical bias in a way that would scale correctly when the keyboard is shown and not shown.
Many answers are right. In AndroidManifest I wrote:
<activity
android:name=".SomeActivity"
android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect.
android:theme="#style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize" />
In my case I added a theme in styles.xml, but you can use your own:
<style name="AppTheme.NoActionBar" parent="AppTheme">
<!-- Hide ActionBar -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
I noiced that if I use full-screen theme, resizing doesn't occur:
<style name="AppTheme.FullScreenTheme" parent="AppTheme">
<!-- Hide ActionBar -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<!-- Hide StatusBar -->
<item name="android:windowFullscreen">true</item>
</style>
Also in my case adjustResize works, but adjustPan doesn't.
For full-screen layouts see a workaround in Android How to adjust layout in Full Screen Mode when softkeyboard is visible or in https://gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584.
Also https://medium.com/#sandeeptengale/problem-solved-3-android-full-screen-view-translucent-scrollview-adjustresize-keyboard-b0547c7ced32 works, but it's StatusBar is transparent, so battery, clock, Wi-Fi icons are visible.
If you create an activity with File > New > Activity > Fullscreen Activity, where in code is used:
fullscreen_content.systemUiVisibility =
View.SYSTEM_UI_FLAG_LOW_PROFILE or
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
you also won't achieve a result. You can use android:fitsSystemWindows="true" in a root container, but StatusBar appears. So use workarounds from the first link.
You can simply set these options in the AndroidManifest.xml file.
<activity
android:name=".YourACtivityName"
android:windowSoftInputMode="stateVisible|adjustResize">
The use of adjustPan is not recommended by Google because the user may need to close the keyboard to see all the input fields.
More info: Android App Manifest
For me it worked with this line of code:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Just put it into onCreate method.
Best!
Add this line into Manifiest File:
android:windowSoftInputMode="adjustResize"
In Kotlin or in ConstraintLayout you just add :
android:windowSoftInputMode="stateHidden|adjustResize"
OR
android:windowSoftInputMode="stateVisible|adjustResize"
Which state you need after activity launch, you can set from manifest.
in your AndroidManifest.xml like this:
<activity
android:name=".ActivityName"
android:windowSoftInputMode="stateHidden|adjustResize"
/>
Easy way in kotlin
In your fragment
requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
In your layout :
android:fitsSystemWindows="true"
In my case it helped.
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.livewallpaper.profileview.loginact.Main2Activity">
<TextView
android:layout_weight="1"
android:layout_width="match_parent"
android:text="Title"
android:gravity="center"
android:layout_height="0dp" />
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
<EditText
android:hint="enter here"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:layout_weight="1"
android:text="signup for App"
android:gravity="bottom|center_horizontal"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
Use this in manifest file
<activity android:name=".MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>
Now the most important part!
Use theme like this in either Activity or Application tag.
android:theme="#style/AppTheme"
And the theme tooks like this
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
So I was missing the theme. Which made me frustrated all day.
I use this Extended class frame
And when I need to recalculate the height size onLayout I override onmeasure
and subtract keyboardHeight using getKeyboardHeight()
My create frame who needs resize with softkeyboard
SizeNotifierFrameLayout frameLayout = new SizeNotifierFrameLayout(context) {
private boolean first = true;
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
fixLayoutInternal(first);
first = false;
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - getKeyboardHeight(), MeasureSpec.EXACTLY));
}
#Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
if (child == actionBar) {
parentLayout.drawHeaderShadow(canvas, actionBar.getMeasuredHeight());
}
return result;
}
};
SizeNotifierFrameLayout
public class SizeNotifierFrameLayout extends FrameLayout {
public interface SizeNotifierFrameLayoutDelegate {
void onSizeChanged(int keyboardHeight, boolean isWidthGreater);
}
private Rect rect = new Rect();
private Drawable backgroundDrawable;
private int keyboardHeight;
private int bottomClip;
private SizeNotifierFrameLayoutDelegate delegate;
private boolean occupyStatusBar = true;
public SizeNotifierFrameLayout(Context context) {
super(context);
setWillNotDraw(false);
}
public Drawable getBackgroundImage() {
return backgroundDrawable;
}
public void setBackgroundImage(Drawable bitmap) {
backgroundDrawable = bitmap;
invalidate();
}
public int getKeyboardHeight() {
View rootView = getRootView();
getWindowVisibleDisplayFrame(rect);
int usableViewHeight = rootView.getHeight() - (rect.top != 0 ? AndroidUtilities.statusBarHeight : 0) - AndroidUtilities.getViewInset(rootView);
return usableViewHeight - (rect.bottom - rect.top);
}
public void notifyHeightChanged() {
if (delegate != null) {
keyboardHeight = getKeyboardHeight();
final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y;
post(new Runnable() {
#Override
public void run() {
if (delegate != null) {
delegate.onSizeChanged(keyboardHeight, isWidthGreater);
}
}
});
}
}
public void setBottomClip(int value) {
bottomClip = value;
}
public void setDelegate(SizeNotifierFrameLayoutDelegate delegate) {
this.delegate = delegate;
}
public void setOccupyStatusBar(boolean value) {
occupyStatusBar = value;
}
protected boolean isActionBarVisible() {
return true;
}
#Override
protected void onDraw(Canvas canvas) {
if (backgroundDrawable != null) {
if (backgroundDrawable instanceof ColorDrawable) {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip);
}
backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
backgroundDrawable.draw(canvas);
if (bottomClip != 0) {
canvas.restore();
}
} else if (backgroundDrawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) backgroundDrawable;
if (bitmapDrawable.getTileModeX() == Shader.TileMode.REPEAT) {
canvas.save();
float scale = 2.0f / AndroidUtilities.density;
canvas.scale(scale, scale);
backgroundDrawable.setBounds(0, 0, (int) Math.ceil(getMeasuredWidth() / scale), (int) Math.ceil(getMeasuredHeight() / scale));
backgroundDrawable.draw(canvas);
canvas.restore();
} else {
int actionBarHeight =
(isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int viewHeight = getMeasuredHeight() - actionBarHeight;
float scaleX = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth();
float scaleY = (float) (viewHeight + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight();
float scale = scaleX < scaleY ? scaleY : scaleX;
int width = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale);
int height = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale);
int x = (getMeasuredWidth() - width) / 2;
int y = (viewHeight - height + keyboardHeight) / 2 + actionBarHeight;
canvas.save();
canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
backgroundDrawable.setBounds(x, y, x + width, y + height);
backgroundDrawable.draw(canvas);
canvas.restore();
}
}
} else {
super.onDraw(canvas);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
notifyHeightChanged();
}
}
This code works for me. When keyboard appears, you can scroll screen
In AndroidManifest.xml
<activity android:name=".signup.screen_2.SignUpNameAndPasswordActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
</activity>
activity_sign_up.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".signup.screen_2.SignUpNameAndPasswordActivity">
<LinearLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_marginTop="#dimen/dp_24"
android:layout_marginStart="#dimen/dp_24"
android:layout_marginEnd="#dimen/dp_24"
android:id="#+id/lin_name_password"
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:layout_gravity="center_horizontal"
android:fontFamily="sans-serif-medium"
android:text="#string/name_and_password"
android:textColor="#color/colorBlack"
android:layout_marginTop="#dimen/dp_5"
android:textSize="#dimen/ts_16"/>
<EditText
android:id="#+id/edit_full_name"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
app:layout_constraintTop_toTopOf="parent"
android:hint="#string/email_address_hint"
android:inputType="textPersonName"
android:imeOptions="flagNoFullscreen"
android:textSize="#dimen/ts_15"
android:background="#drawable/rounded_border_edittext"
android:layout_marginTop="#dimen/dp_15"
android:paddingStart="#dimen/dp_8"
android:paddingEnd="#dimen/dp_8"
android:maxLength="100"
android:maxLines="1"/>
<EditText
android:id="#+id/edit_password"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
app:layout_constraintTop_toTopOf="parent"
android:hint="#string/password"
android:inputType="textPassword"
android:imeOptions="flagNoFullscreen"
android:textSize="#dimen/ts_15"
android:background="#drawable/rounded_border_edittext"
android:layout_marginTop="#dimen/dp_15"
android:paddingStart="#dimen/dp_8"
android:paddingEnd="#dimen/dp_8"
android:maxLength="100"
android:maxLines="1"/>
<TextView
android:id="#+id/btn_continue_and_sync_contacts"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:layout_marginTop="#dimen/dp_15"
android:background="#drawable/btn_blue_selector"
android:enabled="false"
android:text="#string/continue_and_sync_contacts"
android:textColor="#color/colorWhite"
android:textSize="#dimen/ts_15"
android:textStyle="bold"/>
<TextView
android:id="#+id/btn_continue_without_syncing_contacts"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:layout_marginTop="#dimen/dp_10"
android:enabled="false"
android:text="#string/continue_without_syncing_contacts"
android:textColor="#color/colorBlue"
android:textSize="#dimen/ts_15"
android:textStyle="bold"/>
</LinearLayout>
<!--RelativeLayout is scaled when keyboard appears-->
<RelativeLayout
android:layout_marginStart="#dimen/dp_24"
android:layout_marginEnd="#dimen/dp_24"
android:layout_marginBottom="#dimen/dp_20"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tv_learn_more_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:layout_gravity="center_horizontal"
android:text="#string/learn_more_syncing_contacts"
android:textColor="#color/black_alpha_70"
android:gravity="center"
android:layout_marginBottom="1dp"
android:textSize="#dimen/ts_13"/>
<TextView
android:id="#+id/tv_learn_more_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:layout_gravity="center_horizontal"
android:text="#string/learn_more"
android:fontFamily="sans-serif-medium"
android:textColor="#color/black_alpha_70"
android:textSize="#dimen/ts_13"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>
rounded_border_edittext.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape android:shape="rectangle">
<solid android:color="#F6F6F6"/>
<corners android:radius="3dp"/>
<stroke
android:width="1dp"
android:color="#color/red"/>
</shape>
</item>
<item android:state_activated="false">
<shape android:shape="rectangle">
<solid android:color="#F6F6F6"/>
<corners android:radius="3dp"/>
<stroke
android:width="1dp"
android:color="#color/colorGray"/>
</shape>
</item>
</selector>
btn_blue_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="#color/colorBlueLight"/>
<stroke android:width="1dp" android:color="#color/colorBlueLight"/>
</shape>
</item>
<item android:state_enabled="true">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="#color/colorBlue"/>
<stroke android:width="1dp" android:color="#color/colorBlue"/>
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="#color/colorBlueAlpha"/>
<stroke android:width="0dp" android:color="#color/colorBlueAlpha"/>
</shape>
</item>
</selector>
In my case only this solution worked:
In Manifest:
<activity
android:name=".TTSpeech"
android:windowSoftInputMode="adjustPan"
android:exported="false" />
In Activity call
clearFocus();
on edittext.
In Xamarin register below code in your activity
WindowSoftInputMode = Android.Views.SoftInput.AdjustResize | Android.Views.SoftInput.AdjustPan
I used a Relative Layout if you're using Constraint Layout, the above code will work code below

Customizing autocompletetextview

I need to implement a custom search functionality with autocomplete feature with custom adapter. I wrote my own custom adapter, Code is given below:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/icon_bg"
android:orientation="vertical"
tools:context="com.emc.kulkaa.myfinancials.MainActivity">
<AutoCompleteTextView
android:id="#+id/edt_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_alignStart="#+id/imageView"
android:layout_below="#+id/imageView"
android:layout_margin="16dp"
android:layout_marginTop="20dp"
android:background="#drawable/round_border_edittext"
android:drawableEnd="#drawable/clear"
android:drawableLeft="#drawable/white"
android:drawableStart="#drawable/white"
android:ems="10"
android:hint="#string/search_hint"
android:singleLine="true"
android:textColor="#color/colorWhite"
android:textColorHint="#color/colorWhite" />
</LinearLayout>
custom_item.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:background="#color/cardview_color">
<TextView
android:id="#+id/autoCompleteItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="15sp"
style="#style/simple"/>
</LinearLayout>
styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name = "android:autoCompleteTextViewStyle">#style/simple</item>
</style>
<style name="simple" parent="Widget.AppCompat.AutoCompleteTextView">
<item name="android:popupBackground">#drawable/simpleautocustom </item>
</style>
</resources>
simpleautocustom.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/colorWhite" />
<stroke
android:width="0dip"
android:color="#color/colorBlue" />
<corners android:radius="20dip" />
<padding
android:bottom="10dip"
android:left="25dip"
android:right="25dip"
android:top="10dip" />
</shape>
java code
public class MainActivity extends AppCompatActivity {
AutoCompleteTextView mEdtSearch;
#Override
protected void onCreate(Bundle savedInstanceState) {
String arr[] = {"DSA LSA", "CHILD", "AICHILES", "CHILDREN", "FRANCE", "FRENCH"};
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.custom_item, R.id.autoCompleteItem, arr);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEdtSearch = (AutoCompleteTextView) findViewById(R.id.edt_search);
mEdtSearch.setFocusable(true);
mEdtSearch.setFocusableInTouchMode(true);
mEdtSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mEdtSearch.setAdapter(adapter);
}
});
}
}
Above code works fine, here is the screenshot of output:
However it doesn't still match expected output UI which is given below:
How can I change styles and custom shape so that I can achieve the output?
I have tried something for you, hope it will solve your problem and you can customize xmls i.e background of custom_item.xml TextView according to your need.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#9A000000"
android:orientation="vertical">
<AutoCompleteTextView
android:id="#+id/edt_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_alignStart="#+id/imageView"
android:layout_below="#+id/imageView"
android:layout_margin="16dp"
android:layout_marginTop="20dp"
android:background="#drawable/round_border_edittext"
android:drawableEnd="#drawable/clear"
android:drawableLeft="#drawable/white"
android:drawableStart="#drawable/white"
android:ems="10"
android:hint="#string/search_hint"
android:popupBackground="#android:color/transparent"
android:singleLine="true"
android:textColor="#color/colorWhite"
android:textColorHint="#color/colorWhite"/>
</LinearLayout>
custom_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<TextView
android:id="#+id/autoCompleteItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/bg_rounded_border"
android:maxLines="1"
android:padding="15dp"
android:singleLine="true"
android:textColor="#color/white"
android:textSize="15sp"/>
</RelativeLayout>
bg_rounded_border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/hint_color"/>
<corners android:radius="#dimen/padding_less"/>
</shape>
rest your MainActivity (java) code is same, there is no need to set a style to your list item text view.
Here is the screen shot of the output.
You can remove styles.
Only you should add android:padding="7dp" to parent LinearLayout and android:background="#drawable/simple_auto" to TextView in custom_item. It is working.
custom_item:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:padding="7dp"
android:background="#color/cardview_color">
<TextView
android:id="#+id/autoCompleteItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/simple_auto"
android:padding="10dp"
android:textSize="15sp"/>
</LinearLayout>

Java android NavigationView with checkbox

I want to create a NavigationView with checkbox or switch , I just want to have this feature in my navigation to items switch and it should work just like this : When I turn one switch to another it changes to off state. What I did to have a switch is, this :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.SwitchCompat
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:id="#+id/switchs"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_menu1"
android:icon="#mipmap/ic_launcher"
android:title="Menu 1" />
<item
android:id="#+id/nav_menu2"
android:icon="#mipmap/ic_launcher"
android:title="Menu 2" />
<item
android:id="#+id/nav_menu3"
app:actionLayout="#layout/action_view_switch"
android:icon="#mipmap/ic_launcher"
android:title="Menu 3" />
<item
android:id="#+id/nav_menu4"
app:actionLayout="#layout/action_view_switch"
android:icon="#mipmap/ic_launcher"
android:title="Menu 4" />
</group>
</menu>
But I can not have a value or status a switch and have a listener to see a change status
first of all create a layout action_view_checkbox.xml as below
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/checkbox" />
<android.support.v7.widget.AppCompatCheckBox
android:id="#+id/checkbox"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:text="" />
</RelativeLayout>
and add layout as an item to the menu
<menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/check_box_menu"
app:actionLayout="#layout/action_view_checkbox"
android:title="Title" />
</menu>
And check click event as
Menu menu = navigationView.getMenu();
MenuItem menuItem = menu.findItem(R.id.check_box_menu);
View actionView = MenuItemCompat.getActionView(menuItem);
actionView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});

Dynamic number of buttons in LinearLayout

In the onCreate method of my Activity I know the number of Buttons which I want in col0. In the following example it are four Buttons. Then my TextView v0 gets the android:layout_weight set to number of buttons minus one (this is because v1 should be of the same height as all the Buttons). Instead of providing for each possible number of buttons an own xml file it would be much nicer, if one could generalize such that dynamic java codes somehow produces the appropriate layout. How is that possible?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/col0"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:baselineAligned="false"
android:orientation="vertical">
<Button
android:id="#+id/b0"
style="#style/MyButton" />
<Button
android:id="#+id/b1"
style="#style/MyButton" />
<Button
android:id="#+id/b2"
style="#style/MyButton" />
<Button
android:id="#+id/b3"
style="#style/MyButton" />
</LinearLayout>
<LinearLayout
android:id="#+id/col1"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="6"
android:baselineAligned="false"
android:orientation="vertical">
<TextView
android:id="#+id/v0"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="3" />
<TextView
android:id="#+id/v1"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
First prepare all the possible ids, here 10 buttons max (put it in res/values) :
ids.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<item type="id" name="b0" />
<item type="id" name="b1" />
<item type="id" name="b2" />
<item type="id" name="b3" />
<item type="id" name="b4" />
<item type="id" name="b5" />
<item type="id" name="b6" />
<item type="id" name="b7" />
<item type="id" name="b8" />
<item type="id" name="b9" />
</resources>
If you are using API >= 17, you can avoid this file and use View.generateViewId()
If you don't need ids, skip the above part
Then, here is your main layout :
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/col0"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:baselineAligned="false"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="#+id/col1"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="6"
android:baselineAligned="false"
android:orientation="vertical">
<TextView
android:id="#+id/v0" />
<TextView
android:id="#+id/v1"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
Then, use the code to generate your layout :
setContentView(R.layout.main);
int buttonsNumber = 5; // Put here your number of buttons
LinearLayout col0 = (LinearLayout) findViewById(R.id.col0);
for(int i = 0; i < buttonsNumber; i++)
{
try
{
Button newButton = new Button(this);
newButton.setId(R.id.class.getField("b"+i).getInt(null));
// Since API Level 17, you can also use View.generateViewId()
newButton.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
col0.addView(newButton);
}
catch (Exception e)
{
// Unknown button id !
// We skip it
}
}
TextView v0 = (TextView) findViewById(R.id.v0);
v0.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.match_parent, 0, buttonsNumber - 1));
int buttonsNumber = YOUR_BUTTONS_NUMBER;
LinearLayout col0 = (LinearLayout)findViewById(R.layout.col0);
Button button = new Button(getContext()); // or create xml view for button and get it with findViewById
// adding buttons
for(int i = 0; i < buttonsNumber; i++)
col0.addView(button);
// setting weight
TextView v0 = (TextView)findViewById(R.layout.v0);
v0.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.match_parent, 0, buttonsNumber - 1));

Categories

Resources