Custom SwitchPreferenceCompat in androidx - androidx

I'm trying to change default switch thumb in preference screen to my custom. I've tried different solutions found here but none of them working. My last try was to create a custom layout but the problem is that I can't properly add switch to that layout. Can't really add androidx.appcompat.widget.SwitchCompat because of the id (#android:id/switch_widget requires API level 24 (current min is 21) or with other suggested id: Cannot resolve symbol '#android:id/switchWidget').
root_preferences.xml (part):
<PreferenceCategory app:title="#string/confidentiality"
android:layout="#layout/preferences_category">
<SwitchPreferenceCompat
android:layout="#layout/switch_preference_compat"
app:key="show_contacts"
app:title="#string/contact_information"
app:singleLineTitle="false"
app:defaultValue="true"
app:iconSpaceReserved="false"/>
</PreferenceCategory>
switch_preference_compat.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
<TextView
android:id="#android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/ks_font_data"
android:textSize="18sp"/>
<TextView
android:id="#android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"/>
</LinearLayout>
<androidx.appcompat.widget.SwitchCompat
android:id="#android:id/switchWidget" <--- error here
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
I tried styles but it also didn't work well. I want my thumb looks like this[my custom switch][1]
[1]: https://i.stack.imgur.com/Js5vb.png

So after a few hours I was able to find out how to do that. Posting this answer so it may help somebody save their time.
In root_preferences.xml there is android:widgetLayout property where you can set custom layout for SwitchPreferenceCompat:
<SwitchPreferenceCompat
android:widgetLayout="#layout/switch_preference_compat"
app:key="show_contacts"
app:title="#string/contact_information"
app:singleLineTitle="false"
app:defaultValue="true"
app:iconSpaceReserved="false"/>
switch_preference_compat.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
<TextView
android:id="#android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"/>
<TextView
android:id="#android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"/>
</LinearLayout>
<androidx.appcompat.widget.SwitchCompat
android:id="#+id/switchWidget"
android:thumb="#drawable/thumb"
app:track="#drawable/track"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
there is where you put your drawables for custom thumb and track. Mine looks so:
thumb.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:drawable="#drawable/switch_icon_false" />
<item android:state_checked="true"
android:drawable="#drawable/switch_icon_true"/>
</selector>
track.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false">
<shape android:shape="rectangle">
<solid android:color="#dedede"/>
<corners android:radius="100sp"/>
<stroke android:color="#dedede"
android:width="1dp"/>
</shape>
</item>
<item android:state_checked="true">
<shape android:shape="rectangle">
<solid android:color="#9dcbb5"/>
<corners android:radius="100sp"/>
</shape>
</item>
</selector>

Related

AndroidX Fragment recyclerview appearing over my toolbar and I need the recyclerview to scroll under the toolbar

I've created a AndroidX app using a main Activity with fragments. When I go to my fragment with the recyclerview the recycler view appears over the toolbar for the app. What I need is for the recyclerview to appear below the tool bar...
This is the main view with toolbar
This is the fragment with the recyclerview appearing over that toolbar :
Code for activity_mail.xml :
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar"/>
<FrameLayout
android:id="#+id/fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#id/bottom_nav_view"
app:layout_constraintEnd_toEndOf="#id/toolbar"
app:layout_constraintStart_toStartOf="#id/toolbar"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/toolbar"/>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
app:itemBackground="#color/colorPrimaryDark"
app:itemTextColor="#drawable/nav_item_text"
app:itemIconTint="#drawable/nav_background"
android:layout_marginStart="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"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
android:background="#002B49"
app:menu="#menu/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>
EDIT Here is the layout for toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="#+id/products_toolbar"
android:layout_width="match_parent"
app:layout_scrollFlags="enterAlways"
android:background="#null"
android:layout_height="?attr/actionBarSize"
app:titleTextColor="#android:color/black"
local:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/rsi_logo"
android:layout_alignParentStart="true"/>
<ImageButton
android:id="#+id/toolbar_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/menu"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_alignParentEnd="true"
android:contentDescription="#string/menubutton"/>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
As an added note this occurs on fragment's with scrollviews as well.
I tried to replicate your problem (created a repo), but I did not find the issue you specified.
Screenshot: Toolbar is shown
So I say that most probably the issue is with your view.RecyclerFragment code. It seems that you are hiding your the toolbar in your view.RecyclerFragment
It's better if you can share your view.RecyclerFragment code also.

collasping and expanding LinearLayout instead of TabLayout inside AppBarLayout

I have used LinearLayout instead of Tablayout inside AppBarLayout. Please first watch this video link.
I want the same collapsing and extending effect for this LinearLayout as TabLayout has (in this video) when scroll event occurs. I also want toolbar to
to be fixed on the top. just Like the video demo.
My code is below.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.cnpinyin.lastchinese.activities.ViewPagerSlider">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#+id/toolbar_title"
android:textSize="20dp"
android:text="Toolbar title"
android:textColor="#000"
/>
</android.support.v7.widget.Toolbar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="collapse and expands text"/>
</LinearLayout>
</android.support.design.widget.AppBarLayout>
<com.xxx.activities.extras.CustomViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#eeeeee"
android:padding="0dp"
android:layout_below="#id/appbar"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Is it possible to do as I want?

How to put fragment on top of soft kevboard?

I have an Android fragment with a EditText. Since I would like to enter there something, I managed to display the keyboard as well, when opening this fragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/viewgroup_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/viewgroup_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="#+id/view_placeholder"
android:layout_width="match_parent"
android:layout_height="336dp"
android:clickable="false"
android:src="#drawable/img_placeholder_400"
android:layout_weight="0.64" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/margin_bot"
android:paddingLeft="#dimen/margin_left"
android:paddingRight="#dimen/margin_right"
android:paddingTop="20dp"
android:background="#color/dark"
android:focusableInTouchMode="true"
android:weightSum="1">
<RelativeLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter name"
android:id="#+id/textView_fragment_title"
android:textColor="#color/white"
android:clickable="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="You can enter your name here.. "
android:id="#+id/textView_fragment_subtitle"
android:textColor="#color/blueTone" />
</LinearLayout>
<ImageButton
android:id="#+id/btn_close_fragment_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="#drawable/ic_darkblue_20"
android:layout_gravity="right"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="#+id/editText_fragment_content"
android:background="#color/white"
android:inputType="text"
android:imeOptions="actionDone"
android:hint="Enter name here ..."
android:layout_marginTop="10dp">
<requestFocus/>
</EditText>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
But my keyboard is in front of my fragment, and thus my fragment is not visible anymore.
I would like to have my keyboard on the bottom, and on top of my soft keybaord my fragment as in this example screenshot
How can I put my fragment on top of the Android soft keyboard?
Following solved my issue:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/viewgroup_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:focusableInTouchMode="true"
android:layout_alignParentBottom="true"
android:weightSum="1">
<MY_STUFF>
</LinearLayout>
</RelativeLayout>

Android LinearLayout does not left align contents

I want to create a horizontal line of small images thumbnails on top of the display. They should be lined up from left to write (all floated left). When you click on a thumbnail, its bigger version should be displayed below this line. I decided to go with a horizontal LinearLayout (see the one with ID = galleryLayout). It should be a LinearLayout because I want to use it later within a HorizontalScrollView. Here is my layout code:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffef3a"
android:orientation="vertical"
tools:context=".Gallery01">
<LinearLayout
android:id="#+id/galleryLayout"
android:orientation="horizontal"
android:gravity="left"
android:layout_width="match_parent"
android:layout_height="120dp"
android:background="#ffff3e34">
<ImageView
android:src="#drawable/pic02"
android:layout_gravity="left"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:id="#+id/image1"
android:scaleType="fitXY"
android:layout_width="320dp"
android:layout_height="320dp" />
</LinearLayout>
But the problem is that the image is displayed in the center of the layout as you can see here:
As you can see the gravity in the LinearLayout does not work and the image is displayed in the center horizontally. The gravity of the ImageView itself does not work as well (that is just an attempt to make it work!).
Do you guys have any idea what I am doing wrong? Thank you for help!!
I could manage to resolve the problem step by step. Here the results:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#000000"
xmlns:android="http://schemas.android.com/apk/res/android">
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="120dp"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ffffff">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:gravity="left"
android:background="#000000"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:src="#drawable/pic01"
android:layout_width="120dp"
android:layout_height="120dp"
android:padding="10dp"
android:background="#000000" />
<ImageView
android:src="#drawable/pic05"
android:layout_width="120dp"
android:layout_height="120dp"
android:padding="10dp"
android:background="#000000" />
<ImageView
android:src="#drawable/pic03"
android:layout_width="120dp"
android:layout_height="120dp"
android:padding="10dp"
android:background="#000000" />
<ImageView
android:src="#drawable/pic04"
android:layout_width="120dp"
android:layout_height="120dp"
android:padding="10dp"
android:background="#000000" />
</LinearLayout>
</HorizontalScrollView>
<ImageView
android:src="#drawable/pic01"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
It works perfectly :-)

FragmentTabHost with horizontal scroll

I am trying to build a FragmentTabHost and make it horizontal Scrollable. I've been searching for a solution but couldn't find anything, all posts are about normal TabHost.
I am using the support library as explained in the android site for FragmentTabHost
My layout is :
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:tag="trip_entry_tab"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
Already tried to nest the tabwidget into an horizontal scroll view (this is the solution I could find in other posts, but always for TabHost and not for FragmentTabHost), but nothing changes:
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="none" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TabWidget>
</HorizontalScrollView>
My tabs just got shrinked and that is really not nice looking. Has somebody make it to get a fragment tab host scrollable?
Thanks
Based on my experience, the FragmentTabHost doesn't care much about the xml definitions, things must be made programmatically. I got it working by leaving out the HorizontalScrollView from the xml and adding it in my onCreate for the FragmentActivity.
The xml:
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
Then in the onCreate after adding the tabs (also programmatically):
TabWidget tw = (TabWidget) findViewById(android.R.id.tabs);
LinearLayout ll = (LinearLayout) tw.getParent();
HorizontalScrollView hs = new HorizontalScrollView(this);
hs.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
ll.addView(hs, 0);
ll.removeView(tw);
hs.addView(tw);
hs.setHorizontalScrollBarEnabled(false);
Don't know if this is the most elegant solution but it seems to work OK.
I was trying various scenarios, and the one that works for me with XML layout is:
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="none" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</HorizontalScrollView>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
It works fine, the tabs are offscreen to the right an can be 'scrolled' to. Also note, I do not use the "#+id/realtabcontent" FrameLayout.
Resources used:
http://developer.android.com/reference/android/support/v4/app/FragmentTabHost.html
https://maxalley.wordpress.com/2013/05/18/android-creating-a-tab-layout-with-fragmenttabhost-and-fragments/
Regards

Resources