androidx cardview settings lost when running on emulator - androidx

I have a recyclerview with cardview for each item. The layout looks fine from Android Studio design. But when it is running on Emulator and inspecting the layout, some of the cardview settings are changed and the layout is different from design page.
Here is the design along with the XML layout file:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="com.example.androidclient.me.ui.SchoolListViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="80dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="80dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:itemCount="20"
tools:listitem="#layout/school_list_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
The cardview layout file is:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<com.google.android.material.card.MaterialCardView
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
app:cardBackgroundColor="#color/design_default_color_error"
app:cardCornerRadius="4dp"
app:cardElevation="8dp"
app:contentPadding="8dp"
app:contentPaddingBottom="10dp">
<TextView
android:id="#+id/school_list_item_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
tools:text="school name" />
</com.google.android.material.card.MaterialCardView>
</layout>
Here is what is shown on the emulator along with the layout inspection of cardview:
The dependency section in the app build.gradle is:
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.6.1'
// Retrofit with Moshi Converter
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
// paging
implementation "androidx.paging:paging-runtime:3.1.1"
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

Related

Custom SwitchPreferenceCompat in 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>

How to add NavHostFragment in a Fragment destination?

My goal is to understand and use the Navigation component in the best way with a complex navigation architecture (I suppose).
To make the global context, I use a main BottomNavigationBar with 5 items. For the management of the fragments associate, I use the example given by Google : https://github.com/googlesamples/android-architecture-components/tree/master/NavigationAdvancedSample.
But my case is a bit more complex than just a bottom bar. In one of the destinations from one of the fragments launched by the bottom bar, I have another RecyclerView menu and a fragment container to navigate between fragments. I put here the important part of my primary graph :
<?xml version="1.0" encoding="utf-8"?>
<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/main"
app:startDestination="#id/mainFragment">
<fragment
android:id="#+id/mainFragment"
android:name="com.exemple.fragment.MainFragment"
android:label="#string/main_label"
tools:layout="#layout/mainFragment">
<action
android:id="#+id/action_mainFragment_to_goScreen"
app:destination="#id/goScreen">
</action>
</fragment>
<fragment
android:id="#+id/goScreen"
android:name="com.exemple.fragment.GoFragment"
android:label="#string/goLabel"
tools:layout="#layout/fragment_go">
<action
android:id="#+id/action_goScreen_to_mainFragment"
app:destination="#id/mainFragment" />
<argument
android:name="arg1"
app:argType="com.exemple.customType"
android:defaultValue="#null"
app:nullable="true" />
<argument
android:name="arg2"
app:argType="string"
android:defaultValue="#null"
app:nullable="true" />
</fragment>
</navigation>
And the xml with the bottom bar which starts this graph :
<?xml version="1.0" encoding="utf-8"?>
<layout 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"
tools:context="com.exemple.MainActivity">
<RelativeLayout
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/fake_toolbar"
android:layout_width="0dp"
android:layout_height="0dp"/>
<androidx.fragment.app.FragmentTabHost
android:id="#+id/main_host_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottom_navigation" />
<!-- navigation bottom -->
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_alignParentBottom="true"
android:background="#color/navigationBarColor"
app:itemIconTint="#color/textColorNavigationBar"
app:itemTextColor="#color/textColorNavigationBar"
app:menu="#menu/menu_bottom_navigation" />
</RelativeLayout>
</layout>
And here is an example of the graph corresponding to the go fragment (the destination ):
<?xml version="1.0" encoding="utf-8"?>
<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/go"
app:startDestination="#id/firstGoFragment">
<action android:id="#+id/action_to_firstGoFragment"
app:destination="#id/firstGoFragment"/>
<fragment
android:id="#+id/firstGoFragment"
android:name="com.exemple.go.firstGoFragment"
android:label="#string/firstGoFragmentLabel"
tools:layout="#layout/firstGoFragment" >
</fragment>
<action android:id="#+id/action_to_secondFragment"
app:destination="#id/secondFragment"/>
<fragment
android:id="#+id/secondFragment"
android:name="com.exemple.go.SecondFragment"
android:label="#string/secondFragmentLabel"
tools:layout="#layout/secondFragment" >
</fragment>
</navigation>
The associate xml is :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorGreyLight"
android:clickable="true"
android:focusable="true">
<RelativeLayout
android:id="#+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/quit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="16dp"
android:paddingBottom="15dp"
android:paddingEnd="15dp"
android:paddingTop="15dp"
app:srcCompat="#drawable/ic_quit_white" />
<com.teedji.mobeelity.custom.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="#string/go"
android:textColor="#color/colorWhite"
android:textSize="17sp"
android:textStyle="bold" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/goMenu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorWhite"
android:overScrollMode="never"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/linearLayout3" />
<!-- include fragment child container -->
<fragment
android:id="#+id/go_nav_host_fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/goMenu"
app:navGraph="#navigation/go"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Now, to navigate to the go screen I simply use
findNavController().navigate(MainFragmentDirections.actionMainFragmentToGoScreen(arg1, arg2))
or
findNavController().navigate(R.id. action_mainFragment_to_goScreen)
But when I am on the Go fragment, the navController the I find using findNavController() is still the mainFragment one. So the navigate() fonction didn't find the action id. To solve it, I had to change the navHost programaticaly in the GoFragment like this :
override fun onCreate(savedInstanceState: Bundle?) {
Log.i(LOG_TAG, "onCreate")
super.onCreate(savedInstanceState)
if( fragmentManager != null ) {
// If the Nav Host fragment exists, return it
val existingFragment = fragmentManager!!.findFragmentByTag(FRAGMENT_TAG) as NavHostFragment?
existingFragment?.let { navHostGoFragment = it }
// Otherwise, create it and return it.
if ( navHostGoFragment == null) {
navHostGoFragment = NavHostFragment.create(R.navigation.go)
fragmentManager!!.beginTransaction()
.add(R.id.go_nav_host_fragment_container, navHostGoFragment!!, FRAGMENT_TAG)
.commit()
}
}else {
Log.e(LOG_TAG, "fragmentManager is null so I can't find the fragment host")
}
}
and then use navHostGoFragment!!.navController.navigate(R.id.action_to_firstGoFragment) to navigate in the new container
But doing like this, my firstFragment is created twice (I can see it on my logs) and that generate some problems like Cannot add the same observer with different lifecycles for example ( I solve this with adding
if (model.getLiveData().hasObservers()) {
model.getLiveData().removeObserver(observer)
}
before
model.getLiveData().observe(viewLifecycleOwner, observer)
)
But I think I am not doing the Navigation part like I should...
Could you provide any help to make this work more efficiently with stability ?
Try to use go_nav_host_fragment_container.findNavController().navigate(), if you are using Kotlin Android Extensions or findViewById(R.id.go_nav_host_fragment_container).findNavController().navigate(), and see if it works.

Xamarin.forms tabbed page

When i am trying to use toolbar getting following error at runtime.
Android.Views.InflateException: Binary XML file line #1: Binary XML file line #1: Error inflating class android.support.design.widget.Toolbar
Also I am not able to access toolbar of Android.Support.V7.Widget it gives me error
CS0234 C# The type or namespace name does not exist in the namespace (are you missing an assembly reference?)
This is my TabbedPage Layout. Try using this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EDEDED"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabTextColor="#000000"
app:tabSelectedTextColor="#d99a33"
app:tabIndicatorColor="#d99a33"
app:tabGravity="fill"
app:tabMode="scrollable" />
And this is my ToolBar Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#+id/toolbar_title" />
</android.support.v7.widget.Toolbar>

why my MapView don't display anything in fragment?

I am trying to create sample android application that uses the MapView to display the map, but it didn't display anything in fragment.My MapFragment is as follows
<?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">
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

Floating Toolbar with Appcompat

How to create a floating toolbar like the following image as proposed in the material design guidelines and in the Google Map application.
I've worked with the Toolbar before and all the comments from CommonsWare are absolutely correct.
The Toolbar widget (https://developer.android.com/reference/android/support/v7/widget/Toolbar.html) have absolutely nothing special or different than any other Viewgroup and does not behave differently than any other ViewGroup.
Put it inside a FrameLayout, put a layout_margin parameter on it, make the layout_width NOT match_parent and that's it.
Put it inside an LinearLayout with orientation=horizontal and you can use the layout_weight to control the size in percentage. Or just use plain dip if that suits your needs.
Since you are following the Material Design concept I am assuming your are using Coordinator Layout as your Main Layout and Not Frame Layout.
Before anything else we need to declare the important dependencies.
dependencies {
compile 'com.android.support:design:22.2.1'
compile 'com.android.support:cardview-v7:22.2.1'
}
Expected/Similar Output
XML snippet
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:id="#+id/frmlyout_locationnote_mapholder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- You can add your Map here-->
<ImageView
android:id="#+id/imgvw_locationnote_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/tlbr_locationnote_mainmenu"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</android.support.v7.widget.CardView>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_locationnote_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_plus_white_24dp"
app:layout_anchor="#id/frmlyout_locationnote_mapholder"
app:layout_anchorGravity="bottom|right" />
</android.support.design.widget.CoordinatorLayout>
I think Mark's suggestion for picking up the CardView "look" in the comment above deserves this derivative answer:
Just put a Toolbar in a CardView:
<android.support.v7.widget.CardView
android:id="#+id/map_toolbar_container"
android:layout_width="#dimen/whatever_you_want"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardElevation="8dp"
app:cardBackgroundColor="#324">
<android.support.v7.widget.Toolbar
android:id="#+id/wld_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"/>
</android.support.v7.widget.CardView>
Just Add the following code....
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:id="#+id/toolbar"
android:background="#color/colorPrimary"
android:elevation="8dp"
android:layout_margin="5dp"
>
//add whatever elements you want to add in here.
</android.support.v7.widget.Toolbar>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
**android:layout_margin="10dp"
android:elevation="5dp"**
/>
Here is the code for the floating toolbar, just copy and paste.
This is an example of a floating toolbar using Appcompat, It can be working under many layouts like Relative, Coordinator, or DrawerLayout. You can increase elevation to make it more effective.
floating toolbar with Edit text or Search box
<LinearLayout
android:background="#color/colorWhite"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<androidx.appcompat.widget.Toolbar
android:background="#drawable/floating_toolbar"
android:id="#+id/app_toolbar"
android:elevation="2dp"
android:layout_width="match_parent"
android:layout_height="50dp">
<EditText
android:gravity="start"
android:id="#+id/search_bar"
android:background="#drawable/edit_text_no_border"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search here.." />
</androidx.appcompat.widget.Toolbar>
</LinearLayout>
drawable/floating_toolbar.xml file for set background shadows.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid android:color="#6FA5A5A5" />
<corners android:radius="6dp"/>
</shape>
</item>
<item android:top="1dp" android:right="1dp" android:left="1dp" android:bottom="1dp">
<shape
android:shape="rectangle">
<solid android:color="#color/colorWhite"/>
<corners android:radius="5dp"/>
</shape>
</item>
</layer-list>
drawable/edit_text_no_border.xml file for EditText without an outline box or bottom border to make it clean matching background.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffff"/>
<corners android:radius="0px"/>
<stroke android:width="0dp" android:color="#FFFFFF"/>
</shape>
Emoji = ThumbsUp

Resources