I'm trying to set an onclicklistener in my fragment which has a custom toolbar included and in the toolbar I have a bell icon which I am trying to put onclicklistener on but isn't working
This is the toolbar custom_toolbar.xml
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="#string/app_name">
<RelativeLayout
android:id="#+id/notification_bell"
..>
<ImageView
..>
<ImageView
..>
<TextView
..>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
This is the fragment.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".landing.ui.fragment.HomeFragment">
<include android:id="#+id/custom_toolbar"
layout="#layout/custom_toolbar"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Then in Fragment.kt
class HomeFragment : Fragment() {
private fun initbell(notificationCount:Int) {
custom_toolbar.notification_bell.setOnClickListener {
Log.e("Fragment","bell clicked")
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
init()
.........
}
private fun init() {
initComponent()
..........
}
private fun initComponent() {
initbell(it)
..........
}
}
}
When the bell is clicked I want to perform some action. Currently, I should be able to display the log.
And also Im able to access it and change its visibility so its not a problem of initiating
Try this,
Add an id to toolbar
<?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"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/tb_toolbar"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="#string/app_name">
<RelativeLayout
android:id="#+id/notification_bell"
android:layout_width="50dp"
android:layout_height="match_parent"
android:background="#color/colorAccent" />
Then inside fragment
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(context as AppCompatActivity).setSupportActionBar(tb_toolbar)
notification_bell.setOnClickListener {
Toast.makeText(context, "Yeaey", Toast.LENGTH_LONG).show()
}
}
Add an id to Toolbar tag in xml and then in kotlin file add bellow line in
onViewCreated method
(context as AppCompatActivity).setSupportActionBar(your_toolbar_id)
your_toolbar_id.notification_bell.setOnClickListener {
Log.d("TAG", "Your Log message here")
}
If what you want is to make the RelativeLayout handle the click, you should add the android:clickable attribute to it:
<RelativeLayout
android:id="#+id/notification_bell"
android:clickable="true"
..>
That's because a RelativeLayout will let the touch event passed from it so the child view can handle the event.
Alternate :-
Take Relative layout as the header in fragment class like this
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".landing.ui.fragment.HomeFragment">
<RelativeLayout
android:id="#+id/header_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
..>
<ImageView
..>
<TextView
..>
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
and in fragment class with onCreate()
header_bar.setOnClickListener {
Log.e("Fragment","bell clicked")
}
So I was looking into it and found that there was a small mistake that is I had to use AppBar Layout which actually solved the problem as the fragment.xml was not able to get the appbar layout so it wasn't recognizing the clicks. After this it worked like a charm
In fragment.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".landing.ui.fragment.HomeFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/custom_toolbar"
layout="#layout/custom_toolbar"/>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Related
I was trying to implement Android NavigationDrawer menu with Base Activity to show navigation drawer for nested activities using Kotlin.
According to tutorial activity_base_drawer.xml contains content_layout, which contains FrameLayout and in this FrameLayout my activity should be rendered.
NavigationDrawer menu itself working fine but it doesn't render activity_main.xml to FrameLayout, so it is always shows content_layout.xml i.e. empty screen.
What I have missed? How could I render activity_main to FrameLayout?
activity_base_drawer.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.BaseDrawerActivity"
tools:openDrawer="start"
android:fitsSystemWindows="true">
<include layout="#layout/content_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_gravity="start"
android:id="#+id/nav_view"
app:headerLayout="#layout/main_drawer_header"
app:menu="#menu/main_drawer_menu"/>
</androidx.drawerlayout.widget.DrawerLayout>
content_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/appBarLayout"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/app_main"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:titleTextColor="#color/app_main_text"/>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/activityContainer"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="#+id/appBarLayout">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
BaseDrawerActivity.kt
open class BaseDrawerActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
lateinit var drawerLayout: DrawerLayout
override fun setContentView(view: View?) {
drawerLayout= layoutInflater.inflate(R.layout.activity_base_drawer, null) as DrawerLayout
val container = drawerLayout.findViewById<FrameLayout>(R.id.activityContainer)
container.addView(view)
super.setContentView(drawerLayout)
val toolbar: Toolbar =drawerLayout.findViewById(R.id.toolBar)
setSupportActionBar(toolbar)
val navigationView:NavigationView=drawerLayout.findViewById(R.id.nav_view)
navigationView.setNavigationItemSelectedListener(this)
val togle=ActionBarDrawerToggle(this#BaseDrawerActivity, drawerLayout, toolbar, R.string.menu_drawer_open, R.string.menu_drawer_close)
drawerLayout.addDrawerListener(togle)
togle.syncState()
}
}
MainActivity.kt
class MainActivity : BaseDrawerActivity() {
var activityMainBinding: ActivityMainBinding? =null
override fun onCreate(savedInstanceState: Bundle?) {
activityMainBinding=ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding!!.root)
super.onCreate(savedInstanceState)
}
}
I'm trying to use view binding to change the visibility of an ImageView in the app bar when I navigate to a certain fragment. The structure of the app is pretty much like the stock Navigation Drawer Activity in Android Studio.
Since the app_bar_main.xml layout is included in activity_main.xml and has an id, I figured I should be able to just inflate the ActivityMainBinding and reference the app bar and its views. So I do like in the documentation to access the binding from the fragment:
private var _binding: FragmentChooseVehicleBinding? = null
private var _mainBinding: ActivityMainBinding? = null
private val binding get() = _binding!!
private val mainBinding get() = _mainBinding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
chooseVehicleViewModel =
ViewModelProvider(this).get(ChooseVehicleViewModel::class.java)
_binding = FragmentChooseVehicleBinding.inflate(inflater, container, false)
_mainBinding = ActivityMainBinding.inflate(layoutInflater)
mainBinding.appBarMain.appBarLogo.visibility = View.GONE //This has no effect in the UI
return binding.root
}
I checked with debugging and the visibility property on appBarLogo changed correctly and is the right value in onStart()/onResume() as well, but the image still appears in the UI.
Another thing I tried is to inflate the app bar view binding directly, like this:
override fun onStart() {
super.onStart()
val binding = AppBarMainBinding.inflate(layoutInflater)
binding.appBarLogo.visibility = View.GONE
}
Still no change in the UI; the image remains visible. The only thing that works is the old findViewById:
override fun onStart() {
super.onStart()
val appBarLogo = activity?.findViewById<ImageView>(R.id.appBarLogo)
appBarLogo?.visibility = View.GONE
}
Any idea what I'm doing wrong? Thanks.
Update: Here are the layout files (thanks Michael):
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<include
android:id="#+id/app_bar_main"
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="#dimen/nav_header_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#drawable/gradient_black"
app:itemIconTint="#color/white"
app:itemTextColor="#FFFFFF"
app:menu="#menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
app_bar_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.company.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#drawable/gradient_red"
app:popupTheme="#style/Theme.company.PopupOverlay">
<ImageView
android:layout_width="match_parent"
android:id="#+id/appBarLogo"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_marginRight="70dp"
app:srcCompat="#drawable/ic_logo_company" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I am learning Kotlin, have done apps in Java before. I now have an activity with an Toolbar, NavigationView and a FragmentView. As I understand this: Fragment Tutorial, it is enough to state the Fragment in the xml file.
I have this activity_main.xml file:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/navigation_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/main_app_bar_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/holo_blue_light"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/main_navigation"
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_header"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/main_app_bar_layout"
app:menu="#menu/navigation_menu" />
<androidx.fragment.app.FragmentContainerView
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_container"
android:name="com.example.android.camerax.tflite.TestFragment"
tools:layout="#layout/fragment_test" />
</androidx.drawerlayout.widget.DrawerLayout>
This is the fragment_test.xml:
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.camerax.tflite.TestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"
android:textAlignment="center"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the Activity:
class CameraActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var fragment: CameraActivityFragment
private lateinit var navigationDrawer: DrawerLayout
private lateinit var toolbar: Toolbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
navigationDrawer = findViewById(R.id.navigation_container)
// Handle user consent update
toolbar = findViewById(R.id.main_toolbar)
setSupportActionBar(toolbar)
val toggle = ActionBarDrawerToggle(
this,
navigationDrawer,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
navigationDrawer.addDrawerListener(toggle)
toggle.syncState()
val navigationView: NavigationView = findViewById(R.id.main_navigation)
navigationView.setNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.show_recordings) {
// Start ListView
}
navigationDrawer.closeDrawer(GravityCompat.START)
return true
}
}
and here is the TestFragment.kt:
class TestFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_test, container, false)
}
companion object {
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
TestFragment().apply {
arguments = Bundle().apply {
}
}
}
}
I have tried to read the link above and also follow this: AndroidTrivia. No success and I really think this is quite basic and should work. When I run the debugger I can see that onCreateView is called in the Fragment, as it should be.
This is how it looks. Sometimes, the text blips on the screen. So seems like something is overwriting the fragment?
screenshot 1
screenshot 2
Edit
After updating the FragmentContainerView with elevation 9dp, the text is shown. But now the Toolbar is hidden, although there is a marginTop for the FragmentContainerView. Screenshot 3
There are two things I would like to suggest here.
First if possible get back to ConstraintLayout as in your last answer. It is not necessary for sure, but would recommend.
Second the blipping might be cause by the difference in elevation since the elevation of NavigationView is different.
So I suggest you add the following to your FragmentContainerView
<androidx.fragment.app.FragmentContainerView
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_container"
android:elevation="9dp"
android:name="com.example.android.camerax.tflite.TestFragment"
tools:layout="#layout/fragment_test" />
9dp since most Android Views like BottomNav etc are upto 8dp
Also would recommend to modify your fragment_test as follows and add the following
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:clickable="true"
android:focusable="true"
tools:context="com.example.android.camerax.tflite.TestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"
android:textAlignment="center"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I am trying to add drawerlayout in my fragment home. I am getting java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY. this error when I tried to attach drawer layout to my fragment.
I have root layout as constraint layout. Firstly I tried with root layout as drawerlayout still I wast getting this exception so I tried adding constraint layout to it but did not work.
It works when I give the hard coded value to height and width as 500dp.
But hard coded value cant be given as it will not be good practice for all devices size it will differ.
Below is my code
drawer layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
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">
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawer"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/fragment_home"
android:visibility="visible" />
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_gravity="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/nav_header"
layout="#layout/nav_header" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadeScrollbars="true"
android:scrollbars="none">
<include
android:id="#+id/menuItems"
layout="#layout/layout_navigation_menu" />
</ScrollView>
</LinearLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Home fragment layout
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fillViewport="true"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include android:id="#+id/app_bar"
layout="#layout/app_bar_main"/>
<RelativeLayout
android:id="#+id/relative_accept"
android:layout_width="match_parent"
android:layout_height="#dimen/margin_55"
android:orientation="horizontal"
android:background="#color/green_500"
app:layout_constraintTop_toBottomOf="#id/app_bar">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textColor="#color/white"
android:layout_marginLeft="#dimen/margin_16"
android:layout_marginStart="#dimen/margin_16"
android:layout_marginRight="#dimen/margin_16"
android:layout_marginEnd="#dimen/margin_16"
android:text="#string/accepting_orders"
android:fontFamily="#font/roboto_regular"
android:textSize="#dimen/text_size_15"
android:layout_alignParentLeft="true"
android:layout_height="wrap_content" />
<Switch
android:id="#+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:track="#drawable/switch_track_selector"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
tools:ignore="UseSwitchCompatOrMaterialXml" />
</RelativeLayout>
<FrameLayout
android:id="#+id/frameLayout_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/relative_accept">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="42dp"
android:layout_marginStart="#dimen/margin_16"
android:layout_marginLeft="#dimen/margin_16"
android:layout_marginTop="#dimen/margin_20"
android:layout_marginEnd="#dimen/margin_16"
android:layout_marginRight="#dimen/margin_16"
android:background="#drawable/grey_drawable"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:tabGravity="fill"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
android:onClick="#{(v)->click.onClick(v)}"
app:tabBackground="#drawable/tab_selector"
app:tabSelectedTextColor="#color/white" />
</FrameLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="#+id/frameLayout_tab" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Home fragment
class HomeFragment : BaseFragment() , View.OnClickListener{
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.drawer_layout_navigation_view, container, false)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
init()
controlInit()
}
override fun init() {
val toggle = ActionBarDrawerToggle(
(activity as MainActivity),
drawer,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
drawer.addDrawerListener(toggle)
tabs.setupWithViewPager(view_pager)
bindViewPagerAdapter(view_pager, (activity as MainActivity))
bindViewPagerTabs(tabs, view_pager)
tabSettings()
}
private fun tabSettings() {
tabs.bringToFront()
view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(
position: Int, positionOffset: Float, positionOffsetP: Int
) {
}
override fun onPageSelected(position: Int) {}
override fun onPageScrollStateChanged(i: Int) {}
})
}
private fun bindViewPagerAdapter(view: ViewPager?, mainActivity: MainActivity) {
val adapter = OrdersAdapter(view?.context!!, childFragmentManager)
view.adapter = adapter
}
private fun bindViewPagerTabs(view: TabLayout, pagerView: ViewPager?) {
view.setupWithViewPager(pagerView, true)
}
private fun controlInit() {
imageView_drawer.setOnClickListener(this)
}
#SuppressLint("WrongConstant")
override fun onClick(p0: View) {
when (p0.id) {
R.id.imageView_drawer -> {
drawer.openDrawer(Gravity.START)
}
}
}
companion object {
#JvmStatic
fun newInstance() =
HomeFragment().apply {}
}
}
Please help with this.Thank you....
Your layout actually worked just fine when I tested it so I am not sure if the issue lies with the layout. However your layout files are overly complex, you don't really need any of the nested layouts that you have and can achieve the same results without. ConstraintLayout was developed with the purpose of simplifying layout hierarchies so you should be able to just use that to organise your child views.
Also the NavigationView component is meant to be used to display a menu from a menu resource, not just to be used as a wrapper for your own. Either choose to display your own menu completely or use their implementation as intended. There is some nice documentation for this on the [Material Design website] here.
So may I suggest you try to cut down on nesting your layouts and then see whether this incidentally fixes your problem.
The hierarchy that you might want would probably look something like this:
drawer_layout.xml
<DrawerLayout>
<include layout="#layout/home" />
<NavigationView />
</DrawerLayout>
home.xml
<ScrollView>
<ConstraintLayout>
<include layout="#layout/app_bar_main"/>
<TextView />
<Switch />
<TabLayout />
<ViewPager />
</ConstraintLayout>
</ScrollView>
I am currently learning about the Conductor framework for Android and have a bit of a problem or misunderstanding of how it works.
I was under the impression that the method
setRetainViewMode(RetainViewMode.RETAIN_DETACH);
would save the states of the views in the controller. To test the behaviour, I added EditText views, entered a value in it and rotated the screen. I also added 2 views with onclick listeners attached, changing the background color onclick
The result of the test was that the EditText views maintained the state and preserved the entered values. But the 2 views, changed back to their original background color (none).
This is the behaviour of the views regardless on which RetainViewMode is set
I have this simple MainActivity (note: I'm writing in Kotlin):
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var router: Router = Conductor.attachRouter(this, controller_container, savedInstanceState)
if (!router.hasRootController()) {
var t : TestController = TestController()
t.retainViewMode = Controller.RetainViewMode.RETAIN_DETACH
router.setRoot(RouterTransaction.with(t))
}
}
companion object doTask {
fun start(activity : Activity) {
val intent = Intent(activity, MainActivity::class.java)
activity.startActivity(intent)
}
}
}
And here is the the TestController:
class TestController : BaseController() {
var i : Int = 0
var h : Int = 0
override fun onViewBound(view: View) {
view.a.setOnClickListener {
i++
if (i % 2 == 0) {
view.a.setBackgroundColor(ContextCompat.getColor(applicationContext, R.color.white))
} else {
view.a.setBackgroundColor(ContextCompat.getColor(applicationContext, R.color.turtle_green))
}
}
view.b.setOnClickListener {
h++
if (h % 2 == 0) {
view.b.setBackgroundColor(ContextCompat.getColor(applicationContext, R.color.white))
} else {
view.b.setBackgroundColor(ContextCompat.getColor(applicationContext, R.color.blue_light))
}
}
}
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
return inflater.inflate(R.layout.controller_layout_test, container, false)
}
}
And xml layout file controller_layout_test:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<requestFocus></requestFocus>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/logo_simple"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="30dp"
android:layout_gravity="center"
android:background="#color/transparent50p"
android:padding="20dp">
<EditText
android:id="#+id/gt"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:padding="6dp"
android:background="#color/white_transparent50p"/>
/>
<EditText
android:id="#+id/erergeargf"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:padding="6dp"
android:background="#color/white_transparent50p"/>
<View
android:id="#+id/a"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="5dp"
android:layout_gravity="center"></View>
<View
android:id="#+id/b"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="5dp"
android:layout_gravity="center"></View>
</LinearLayout>
</ScrollView>
</FrameLayout>
activity_main xml layout looks like this:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="dk.minreklame.minetilbud_v2.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
/>
</android.support.design.widget.AppBarLayout>
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
android:id="#+id/controller_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>
As your views have references to the host Activity, they will never be retained across orientation changes. That would cause a memory leak. The docs on RETAIN_DETACH state:
The Controller will retain its reference to its view when detached, but will still release the reference when a config change occurs.