"Ghost" Bottom Navigation Bar when fragment loads in home activity - android

I'm currently working on the home screen of my app and am using fragments to load the different "pages" when a user clicks on a button on a bottom navigation bar. What I've found is that when I load the home screen the bottom bar seems to reload itself again, creating two bars, one in the middle of the page and one in the proper position at the bottom of the screen (while the middle bar isn't actually functional). I'm thinking that the fragment loading in the activity is the cause, but I'm not entirely sure on how to solve it. Below is an image of the problem as well as some of the code that I've got.
activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:design="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/home_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include
layout="#layout/app_bar"
android:layout_width="0dp"
android:layout_height="0dp"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="225dp" />
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<FrameLayout
android:id="#+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#f1f1f1"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="25dp">
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#drawable/shadow" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
design:menu="#menu/bottom_nav_menu"
/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
home_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:design="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/home_fragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp">
<ImageView
android:id="#+id/tokyo_placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitStart"
design:layout_constraintLeft_toLeftOf="parent"
design:layout_constraintRight_toRightOf="parent"
design:layout_constraintTop_toTopOf="parent"
design:srcCompat="#drawable/main_screen_placeholder" />
<ImageView
android:id="#+id/airplane_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="#drawable/circle_background"
design:layout_constraintBottom_toBottomOf="#+id/tokyo_placeholder"
design:layout_constraintLeft_toLeftOf="#+id/tokyo_placeholder"
design:layout_constraintRight_toRightOf="#+id/tokyo_placeholder"
design:layout_constraintTop_toTopOf="#+id/tokyo_placeholder"
design:srcCompat="#drawable/icons8_airplane_48" />
<include
layout="#layout/app_bar"
android:layout_width="0dp"
android:layout_height="0dp"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="225dp" />
<TableLayout
android:layout_width="349dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:orientation="horizontal"
design:layout_constraintLeft_toLeftOf="parent"
design:layout_constraintRight_toRightOf="parent"
design:layout_constraintTop_toBottomOf="#+id/tokyo_placeholder">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/destination_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:text="Featured Destinations"
android:textAllCaps="true"
android:textAppearance="#style/TextAppearance.AppCompat.Headline"
android:textSize="14sp"
android:textStyle="bold" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp">
<HorizontalScrollView
android:id="#+id/horizontal_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp">
<LinearLayout
android:id="#+id/featured_destinations_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/saved_trips_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:text="Saved Trips"
android:textAllCaps="true"
android:textAppearance="#style/TextAppearance.AppCompat.Headline"
android:textSize="14sp"
android:textStyle="bold" />
</TableRow>
</TableLayout>
</android.support.constraint.ConstraintLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:background="#drawable/shadow" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_nav"
elevation="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
design:menu="#menu/bottom_nav_menu" />
</FrameLayout>
<!-- TODO: Make page scrollable and fix bottom navigation bar -->
</android.support.design.widget.CoordinatorLayout>
HomeActivity.kt
package projectrc_android.project_rc
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.design.widget.BottomNavigationView
import android.support.v7.widget.Toolbar
import projectrc_android.project_rc.R.*
class HomeActivity : AppCompatActivity() {
private var current_fragment = id.home_fragment
private val fragmentManager = supportFragmentManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(layout.activity_home)
val toolbar = findViewById(R.id.app_bar) as Toolbar
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false)
val bottomNavigationBar = findViewById(id.bottom_nav) as BottomNavigationView // get bottom navigation bar
bottomNavigationBar.selectedItemId = R.id.home_button // set the selected menu item to home at the start
ShowFragment(R.id.home_button) // load the home fragment item into the activity
var selectedMenuItem = bottomNavigationBar.selectedItemId // get currently selected menu item
bottomNavigationBar.setOnNavigationItemSelectedListener { item ->
if(item.itemId != selectedMenuItem) { // if the user picks a button that's NOT the currently selected one
selectedMenuItem = item.itemId // update the selected menu item
ShowFragment(item.itemId)
}
true
}
}
private fun ShowFragment(menuButton: Int) {
val transaction = fragmentManager.beginTransaction()
when (menuButton) {
R.id.home_button -> {
transaction.replace(R.id.fragment_container, HomeFragment())
current_fragment = R.id.home_fragment
}
R.id.inbox_button -> {
transaction.replace(R.id.fragment_container, InboxFragment())
current_fragment = R.id.inbox_fragment
}
R.id.account_button -> {
transaction.replace(R.id.fragment_container, AccountFragment())
current_fragment = R.id.account_fragment
}
}
transaction.addToBackStack(null)
transaction.commit()
}
}
HomeFragment.kt
package projectrc_android.project_rc
import android.support.v4.app.Fragment;
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
class HomeFragment : Fragment() {
private val imagePaths = intArrayOf(R.drawable.cuba_placeholder, R.drawable.s_korea_placeholder,
R.drawable.greece_placeholder, R.drawable.san_francisco_placeholder, R.drawable.cuba_placeholder, R.drawable.s_korea_placeholder,
R.drawable.greece_placeholder, R.drawable.san_francisco_placeholder)
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View {
var view = inflater!!.inflate(R.layout.home_fragment, container, false)
val destinationGallery = view.findViewById(R.id.featured_destinations_gallery) as LinearLayout
//set up toolbar in place of action bar (and remove title)
//dynamically add images to scrollview
addImageToLayout(view.context, destinationGallery, imagePaths, 260, 360)
return view
}
private fun addImageToLayout(context : Context, layout: LinearLayout, imagePaths: IntArray, width: Int, height: Int) {
val numberOfImages = imagePaths.size
for (index in 0 until numberOfImages) {
val imageView = ImageView(context)
imageView.id = index
imageView.setPadding(2, 2, 2, 2)
Glide
.with(this)
.load(imagePaths[index])
.apply(RequestOptions()
.override(width, height)
.centerCrop())
.into(imageView)
layout.addView(imageView)
}
}
}

You have added android.support.design.widget.BottomNavigationView in both activity_home.xml as well as in home_fragment.xml. So you are seeing two bottom navigation views.
you have set listener to the activity's navigation view But didn't set any listener to the fragment's navigation view and so the one that is shown in the middle is not functional.
Remove navigation view from home_fragment.xml. It should solve the issue.

Related

Getting DrawerLayout must be measured with MeasureSpec.EXACTLY when adding the drawer layout

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>

PagedList.Config loads list in the middle with recycleview

My RecyclerView loads in the middle of the list instead of the most top item first. The list should load the topmost item. In this case, it's the "latest" post. Which I have set to the reverse layout to true and that works.
My RecyclerView
<FrameLayout 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"
tools:viewBindingIgnore="true">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/postsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="5dp"
tools:listitem="#layout/post_item" />
</FrameLayout>
My Post list fragment
// Set up FirebaseRecyclerAdapter with the Query
val postsQuery = database.child(Globals().POSTS_ROOT_PATH)
// This configuration comes from the Paging Support Library
// https://developer.android.com/reference/androidx/paging/PagedList.Config
val config = PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(5)
.setPageSize(10)
.build()
// The options for the adapter combine the paging configuration with query information
// and application-specific options for lifecycle, etc.
val options = DatabasePagingOptions.Builder<Post>()
.setLifecycleOwner(this)
.setQuery(postsQuery, config, Post::class.java)
.build()
adapter = object : FirebaseRecyclerPagingAdapter<Post, PostViewHolder>(options) {
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): PostViewHolder {
val inflater = LayoutInflater.from(viewGroup.context)
return PostViewHolder(inflater.inflate(R.layout.post_item, viewGroup, false))
}
override fun onBindViewHolder(viewHolder: PostViewHolder, position: Int, model: Post) {
val postRef = getRef(position)
// Set click listener for the whole post view
val postKey = postRef.key
// Log.d("PostListFragment", "post key id is: " + postKey)
viewHolder.itemView.setOnClickListener {
// Launch PostDetailActivity
val intent = Intent(activity, PostDetailActivity::class.java)
intent.putExtra(PostDetailActivity.EXTRA_POST_KEY, postKey)
startActivity(intent)
}
}
override fun onLoadingStateChanged(state: LoadingState) {
when (state) {
LoadingState.LOADING_INITIAL -> {
Log.d(TAG, "Initial data loading")
}
LoadingState.LOADING_MORE -> {
}
LoadingState.LOADED -> {
}
LoadingState.FINISHED -> {
Log.d(TAG, "All data loaded.")
}
LoadingState.ERROR -> {
Log.d(TAG, "Error occured while loading data")
}
}
}
override fun onError(databaseError: DatabaseError) {
super.onError(databaseError)
databaseError.toException().printStackTrace()
}
}
// Set up Layout Manager, reverse layout
manager = LinearLayoutManager(activity)
manager.reverseLayout = true
manager.stackFromEnd = true
recyclerList.layoutManager = manager
recyclerList.adapter = adapter
}
When I set the setPageSize() to a very large number then it loads the most top item. What do I need to do so this always loads the most top list item first?
Thanks
Edit:
post_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
tools:viewBindingIgnore="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/postTextLayout"
layout="#layout/post_text_include"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp"
android:layout_marginStart="2dp" />
<include
android:id="#+id/postThumbnailImg"
layout="#layout/post_video_thumbnail_include"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/postTextLayout"
android:layout_alignParentStart="true" />
<include
android:id="#+id/postAuthorLayout"
layout="#layout/post_author_thumbnail_include"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/postThumbnailImg"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
Sub layouts
<?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:orientation="vertical">
<TextView
android:id="#+id/postTitle"
style="#style/TextAppearance.AppCompat.Medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textStyle="bold"
android:textColor="#color/colorPrimaryDark"
tools:text="My First Post"
android:paddingStart="5dp"
android:paddingEnd="5dp" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:viewBindingIgnore="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/videoThumbnailImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/main_background" />
/>
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="#+id/playButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="centerCrop"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_baseline_play_arrow_24" />
</RelativeLayout>
</FrameLayout>
<?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="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="40dp"
android:layout_height="40dp"
app:cardCornerRadius="20dp">
<ImageView
android:id="#+id/postAuthorPhoto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/ic_person_outline_40" />
</androidx.cardview.widget.CardView>
<TextView
android:id="#+id/postAuthor"
style="#style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:textColor="#color/colorPrimaryDark"
tools:text="someauthor#email.com" />
</LinearLayout>
You need to set height wrap_content rather than match_parent for sublayouts.

Kotlin update text of textview on different layout from activity

I have a navigation header as bellow
I want to update TextView in nav_header.xml from MainActivity.kt by Kotlin
I want to update text of TextView(id=drawer_user_name) from MainActivity.kt
main_activity.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"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="45dp"
android:background="#android:drawable/screen_background_light_transparent"
tools:listitem="#layout/item_list" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header"
app:menu="#menu/nav_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
nav_header.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:layout_width="match_parent"
android:layout_height="200dp"
android:background="#4cAF50"
android:orientation="vertical"
android:layout_gravity="top"
android:paddingTop="35dp"
android:paddingLeft="15dp"
android:paddingBottom="15dp"
android:id="#+id/ddd">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"
android:id="#+id/imageView"
android:layout_marginBottom="15dp"/>
<TextView
android:id="#+id/drawer_user_name" //--> i want to update this TextView from MainActivity.kt
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="title"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="this our navigation drawer"
android:textColor="#FFFFFF" />
</LinearLayout>
content_main.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="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/colorPrimary"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:id="#+id/home_page_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Chat"
android:textColor="#FFFFFF" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="this is my content"/>
</LinearLayout>
</LinearLayout>
Please Help me,I really need a way to solve this problem
thank you
Babbab forces us to write stories here to allow us to post a question(It looks like your post is mostly code; please add some more details)
Edit
my MainActivity.kt
package com.example.myapplication
...
import android.view.LayoutInflater
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.activity_main_page.*
import kotlinx.android.synthetic.main.nav_header.view.*
class MainPageActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener,CustomAdapter.OnItemClickListener {
lateinit var toolbar:androidx.appcompat.widget.Toolbar
lateinit var drawerLayout: DrawerLayout
lateinit var navView:NavigationView
private var data = arrayListOf<UserChanel>()
private lateinit var myadapter:CustomAdapter
private val gson = Gson()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar =findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
drawerLayout = findViewById(R.id.drawer_layout)
navView = findViewById(R.id.nav_view)
val toggle = ActionBarDrawerToggle(this,drawerLayout,toolbar,0,0)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
navView.setNavigationItemSelectedListener(this)
// val userNameTextView = nav_view.findViewById<TextView>(R.id.drawer_user_name)
// userNameTextView.text = "SOME TEXT" // error
nav_view.drawer_user_name.text = "SOME TEXT" // Error
val recyclerview = findViewById<RecyclerView>(R.id.recycler_view)
// for insert line divider to recyclerview items
recyclerview.addItemDecoration(SimpleDividerItemDecoration(this)) // for insert line divider to recyclerview items
send_request()
val adapter = CustomAdapter(this,data,this)
recyclerview.layoutManager = LinearLayoutManager(this)
recyclerview.adapter = adapter
recyclerview.setHasFixedSize(true)
myadapter = adapter
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when(item.itemId){
R.id.nav_profile->{
Toast.makeText(this,"profile clicked",Toast.LENGTH_SHORT).show()
}
R.id.nav_message->{
Toast.makeText(this,"message clicked",Toast.LENGTH_SHORT).show()
}
R.id.nav_frinds->{
Toast.makeText(this,"frinds clicked",Toast.LENGTH_SHORT).show()
}
R.id.nav_update->{
Toast.makeText(this,"update clicked",Toast.LENGTH_SHORT).show()
}
R.id.nav_logout->{
Toast.makeText(this,"logout clicked",Toast.LENGTH_SHORT).show()
}
}
drawerLayout.closeDrawer(GravityCompat.START)
return true
}
private fun send_request(){
...
}
override fun onItemClick(position: Int,adapter: CustomAdapter,v:View) {
...
}
}
You can find the target view from its parent in your activity like either of these ways:
nav_view.getHeaderView(0).findViewById<TextView>(R.id.drawer_user_name).text = "SOME TEXT"
or
import kotlinx.android.synthetic.main.nav_header.view.*
...
nav_view.getHeaderView(0).drawer_user_name.text = "SOME TEXT"
It's possible to access the header view using getheaderview(int index) according to the documentation. As you have one header view in the NavigationView, it is accessible by index 0.

why does this layout take 2-7 seconds to render in the UI?

So I have a layout with a RecyclerView That is taking between 2 and 7 seconds to load 7 items and show them in the list.
I ran the Android Studio profiler on the CPU using Sample Java methods and it appears that the bulk of the wait time is happening in the drawing and measuring of the views. 60% inRun() from FrameDisplayEventReceiver and nested under that call 53% by the first onMeasure() call.
Correct me if I'm wrong, but it appears that the cause of the slowness is a poorly designed xml layout.
Can any one show my what I've done in this layout that makes it run slowly and how I can make it more efficient?
<?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"
android:background="#color/white"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/id_1"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" >
<ProgressBar
android:id="#+id/id_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="#795548"
android:indeterminateTintMode="src_in"
android:layout_gravity="end"
/>
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:id="#+id/id_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="#id/id_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:srcCompat="#drawable/image_1"
android:contentDescription="#string/description" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="#string/text_1" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/id_4"
android:name="com.company.MyFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/white"
app:layoutManager="LinearLayoutManager"
app:layout_constraintTop_toBottomOf="#id/id_1"
tools:context="MyFragment"
tools:listitem="#layout/fragment_routeitem"
android:visibility="gone"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/id_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin"
android:background="?attr/colorPrimary"
android:tint="#color/white"
app:backgroundTint="?attr/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:rippleColor="?attr/colorPrimary"
app:srcCompat="#drawable/ic_add_white_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is the Code as Request (Kotlin)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_routeitem_list, container, false)
val toolbar: Toolbar = view.findViewById(R.id.toolbar)
toolbar.title = resources.getString(R.string.my_route_title)
progressBar = view.findViewById(R.id.my_routes_loading)
emptyStateView = view.findViewById(R.id.empty_state)
recyclerView = view.findViewById(R.id.my_routs_list)
dataAdapter = MyRouteItemRecyclerViewAdapter(mutableListOf(), this)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = dataAdapter
startLoadData()
val newRouteFab: FloatingActionButton = view.findViewById(R.id.new_route_fab)
newRouteFab.setOnClickListener {
createNewRoute()
}
return view
}
fun startLoadData() {
launch{
val routeList: List<Route> = withContext(Dispatchers.IO){
Application.getDaoSession()
.routeDao
.queryBuilder()
.where(RouteDao.Properties.Id.isNotNull)
.orderDesc(RouteDao.Properties.VisibleModified)
.build().list()
}
setData(routeList.toMutableList())
progressBar.visibility = View.GONE
}
}

add an actionbar for each fragment

Suppose I have 4 fragments that I put in mainActivity, I want to create different actionbar different in each frgament.
When I press fragment 1 then the actionBar appears fragment 1, when I press the two fragment that appears actoinbar belonging to fragment 2
01-02 20:12:33.700 15035-15035/src.go_letskerja E/AndroidRuntime: FATAL EXCEPTION: main
Process: src.go_letskerja, PID: 15035
java.lang.NullPointerException
at src.go_letskerja.Fragment.OtherFragment.onCreateView(OtherFragment.java:26)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5113)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
This my Activity :
package src.go_letskerja.Fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import src.go_letskerja.R;
/**
* A simple {#link Fragment} subclass.
*/
public class OtherFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_other, container, false);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("TES");
//((AppCompatActivity)getActivity()).getSupportActionBar().setCustomView(R.layout.actionbar);
return v;
}
}
This my 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="60dp"
android:fitsSystemWindows="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:text="Tinggi Badan"
android:textSize="14dp" />
<TextView
android:id="#+id/tinggibadan"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="15dp"
android:paddingLeft="30dp"
android:paddingTop="10dp"
android:text="000 Cm"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/list" />
</LinearLayout>
Yes, you can add the custom toolbar to your fragment and make your activity theme with no action bar in the Manifest and do something like this. this layout may be your fragment layout and inflate in your activity.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_alignParentTop="true"
android:background="#color/colorPrimary"
android:gravity="top"
app:titleTextColor="#color/white">
<ImageView
android:id="#+id/iv_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:contentDescription="TODO"
android:visibility="visible"
app:srcCompat="#drawable/ic_back" />
<TextView
android:id="#+id/toolbar_title"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="List Entry"
android:textColor="#color/white"
android:textSize="#dimen/large_text_size" />
<ImageView
android:id="#+id/iv_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_margin="#dimen/middium_padding"
android:contentDescription="TODO"
android:src="#mipmap/add"
android:visibility="visible" />
</android.support.v7.widget.Toolbar>
</RelativeLayout>
and access you toolbar with framgment view.
In this scenario you usually have:
Activity and layout that owns and contains Fragments, let us call them FragmentOwnerActivity.kt and fragment_owner_layout.xml
A class derived from Fragment and a layout associated with it, let us call them MyFragment.kt and my_fragment_layout.xml
To enable toolbars in your fragments you'll need to put the following to my_fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/someid"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyFragment">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="0dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="0dp"
>
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="#attr/actionBarSize"
android:background="#attr/colorPrimary"
android:contentInsetEnd="0dp"
android:contentInsetLeft="0dp"
android:contentInsetRight="0dp"
android:contentInsetStart="0dp"
android:elevation="2dp"
app:contentInsetEnd="0dp"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetStart="0dp"
>
<TextView
android:id="#+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/toolbar_title"
android:textSize="22sp"
android:textStyle="bold" />
</android.support.v7.widget.Toolbar>
In MyFragment.kt you'll need to enable the toolbar:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as AppCompatActivity).setSupportActionBar(view?.findViewById(R.id.my_toolbar))
In FragmentOwnerActivity.kt you'll need to inflate a fragment specific menu and process menu click events
// You'll need to create an xml with a menu for your fragment
// and then use it in inflate function below
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.my_fragment_menu_id, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle item selection
when (item.getItemId()) {
R.id.menu_item1_id -> {
doMenuItem1()
return true
}
R.id.menu_item2_id -> {
doMenuItem2()
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
Finally, your fragment_owner_layout.xml is just FrameLayout element that controls other frames
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyFragmentOwner"/>

Categories

Resources