Android Studio 3.6
in app/build.gradle:
android {
viewBinding.enabled = true
In my activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = QrBluetoothSwipeActivityBinding.inflate(layoutInflater)
}
in my qr_bluetooth_swipe_activity.xml
<include
android:id="#+id/blueToothBottonContainer"
layout="#layout/bluetooth_bottom_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
I want to hide blueToothBottonContainer programmaticaly.
So I try this:
private fun setBottomContainreViewMode(isQrScreenVisible: Boolean) {
if (isQrScreenVisible) {
binding.qrBottonContainer.
}
}
but not found method smt like setVisible
why?
setVisibility method belongs to a View class. <include> tag is not really a layout(View + ViewGroups). That's why you won't find setVisibility method on it.
To hide the included layout, you can give id to parent layout in your bluetooth_bottom_container layout and then change it's visiblity from binding.blueToothBottonContainer.{parent_layout_id}.
Related
I'm writing kotlin code to dynamically add TextView widget.
But I can't get the text in the for loop with compile error("Unresolved reference: text")
how can I solve this problem?
MainActivity.kt
private val vBinding by lazy {ActivityMainBinding.inflate(layoutInflater)}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(vBinding.root)
// add TextView to linearLayout
vBinding.addTopic.setOnClickListener {
val newTV = TextView(this)
newTV.text = "test"
vBinding.linearLayout.addView(newTV)
}
// get a text from textView but don't work
vBinding.submitBtn.setOnClickListener {
for(item in vBinding.linearLayout.children){
Log.d("test", "${item.text}")
}
}
layoutFile.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
...
tools:context=".InputActivity">
<Button
android:id="#+id/submitBtn"
android:text="SAVE" />
<LinearLayout
android:id="#+id/linearLayout"
android:orientation="vertical">
</LinearLayout>
<ImageButton
android:id="#+id/addTopic"
app:srcCompat="#android:drawable/arrow_up_float" />
</androidx.constraintlayout.widget.ConstraintLayout>
for (item in vBinding.linearLayout.children){
Log.d("test", "${(item as TextView).text}")
}
You should cast your children views to TextView. What if there are only image views? Or a recycler? Or something else which doesn't have a "text" property?
You can take a look at this article, it's about type checks/casts in Kotlin.
In my app, there is an activity which needs to be closed on navigation click. In the past, the code below worked perfectly, however, since the new Android changes it doesnt work anymore.
Are there new ways to call the Navigation icon click? Is there something i am missing?
ActivitySettings.kt
class ActivitySettings : AppCompatActivity() {
private lateinit var binder: ActivitySettingsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binder = ActivitySettingsBinding.inflate(layoutInflater)
setContentView(R.layout.activity_settings)
binder.topToolbarBack.setNavigationOnClickListener {
finish()
}
}
}
activity_settings.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/topToolbarBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIconTint="#color/white_material"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="#drawable/ic_outline_arrow_back_24"
app:popupTheme="#style/popupMenuThemeDark"
app:title="#string/currentScreenSettings"
app:titleTextColor="#color/white_material" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvSettings"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/topToolbarBack" />
</androidx.constraintlayout.widget.ConstraintLayout>
please make sure you call setSupportActionBar(binder.topToolbarBack) before you set click listener for the toolbar
This problem is caused by the way the layouts got called.
binder can be considered a "secondary layout". Since in that activity, i set as ContenteView R.layout.activity_settings, the binder, that can still get the elements from the layout, gets basically covered by the layout currently set.
If you want to use binder you must set as inside setContentView() binder.root, which loads the proper layout you need.
So, the code fixed is:
class ActivitySettings : AppCompatActivity() {
private lateinit var binder: ActivitySettingsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binder = ActivitySettingsBinding.inflate(layoutInflater)
setContentView(binder.root)
binder.topToolbarBack.setNavigationOnClickListener {
finish()
}
}
}
I have a activity_main.xml file which looks like this.
<?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="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
tools:context=".MainActivity"
android:id="#+id/main_linear_layout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:layout_gravity="center_horizontal"
android:textSize="30sp"
android:id="#+id/dice_text"/>
<Button
android:id="#+id/roll_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="#string/roll"/>
</LinearLayout>
So when i try to create a view binding and use it in Activity file,
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val root = binding.root
setContentView(root.main_linear_layout)
buttonClicked()
}
fun buttonClicked(): Unit {
val roll_button = binding.mainLinearLayout.roll_button
val text = binding.mainLinearLayout.dice_text
roll_button.setOnClickListener {
var randomNumber = Random().nextInt(6)+1
text.text = randomNumber.toString()
}
}
}
i have some issues. Naturally since the Linear Layout has layout_gravity set to center, it should be centered in the screen, both vertically and horizontally. This is the case in the design editor of the xml which is how it is supposed to be.
But when i run the app, in my phone both the text and button, aligns center_horizontal but not vertically.
I tried giving center_vertical also but doesn't work.
But if i don't use the view binding and use findViewById , it works fine.
Edit: I have removed the mainLinearLayout from the binding. So its just
setContentView(root)
I doesn't work.This is how i want it to be and this is how it is present in the Design View of the xml ( I have removed text and added Image)
But, when i run it, i get this. enter image description here
P.S I have just started learning android development
Adding
android:gravity = "center"
worked!!
Try this :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val root = binding.root
setContentView(root)
buttonClicked()
}
Source: https://developer.android.com/topic/libraries/view-binding#activities
I've followed this tutorial to implement BottomSheetDiaogFragment in my android application.
this is my bottom sheet layout (bottom_sheet.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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioGroup
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RadioButton
android:id="#+id/rb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:text="#string/rb1" />
<RadioButton
android:id="#+id/rb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:text="#string/rb2" />
</RadioGroup>
</android.support.constraint.ConstraintLayout>
BottomSheetDialogFragment class:
class BottomSheetTaskRepeat : BottomSheetDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.bottom_sheet, container, false)
}
}
activity:
private val bottomSheetTaskRepeat = BottomSheetTaskRepeat()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bottomSheetTaskRepeat.show(supportFragmentManager, "my_bottom_sheet")
}
The problem is that the bottom sheet is not showing up! Any help is appreciated.
This is a late Answer, I am writing for anyone who will face the same problem, This is what I found:
For some reasons non-constrained views heights do not work in BottomSheetDialogFragment. A view whose height is like wrap_content will not show.(But the shadow will be there), but when you specify its height like 80dp it works.
For this question go and change your RadioGroup height and specify it like to:
android:layout_height="200dp"
Hope that is helpful.
UPDATE:
Since the default container of BottomSheetDailogFragment is FrameLayout and is set to WRAP_CONTENT, You can override that on your Fragment onStart method like this (Kotlin):
override fun onStart() {
super.onStart()
val containerID = com.google.android.material.R.id.design_bottom_sheet
val bottomSheet: FrameLayout? = dialog?.findViewById(containerID)
bottomSheet?.let {
BottomSheetBehavior.from<FrameLayout?>(it).state =
BottomSheetBehavior.STATE_HALF_EXPANDED
bottomSheet.layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT
}
view?.post {
val params = (view?.parent as View).layoutParams as (CoordinatorLayout.LayoutParams)
val behavior = params.behavior
val bottomSheetBehavior = behavior as (BottomSheetBehavior)
bottomSheetBehavior.peekHeight = view?.measuredHeight ?: 0
(bottomSheet?.parent as? View)?.setBackgroundColor(Color.TRANSPARENT)
}
}
Try following:
Create and use the parameterless static method newInstance in your BottomSheetDialogFragment and call the show() method on it.
Try LinearLayoutCompat as a root layout instead of ConstraintLayout.
Try a colourful background to the root layout to get an idea.
Try match_parent height for the root layout.
Make sure that the dismiss() or cancel() is not being called on it immediately.
Check visibility.
If it contains a recyclerView, make sure that it has items, getItemCount is not returning 0, and that we are setting up the values properly!
Restart both: PC and Device if your changes are not reflecting because of Android Studio errors.
Instead of using supportFragmentManager you have to use childFragmentManager,if you are inflating from inner fragments.
private val bottomSheetTaskRepeat = BottomSheetTaskRepeat()
bottomSheetTaskRepeat.show(childFragmentManager, "my_bottom_sheet")
So I have this MainLayout which simply consists of a Floating Action Button (FAB) right now:
<RelativeLayout 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/lel"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.FloatingActionButton
android:id="#+id/floatingActionButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:clickable="true"
android:src="#drawable/ic_add_black_24dp" />
</RelativeLayout>
I am using this library to create a treeView similar to this
I create the AndroidTreeView object in the MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val treeView = AndroidTreeView(this, root) // 'this' is the context
// ...
setContentView(treeView.view)
}
This will obviously only display the content of the treeView and not the mainLayout.
How can I show the TreeView and the Button at the same time / render the TreeView on top of the MainLayout?
I tried to add the FAB to the view using addView:
val view = treeView.view as ViewGroup
view.addView(floatingActionButton2)
But this results in a java.lang.IllegalStateException: ScrollView can host only one direct child
In an example project the author of TreeView used Fragments for this. But is this really necessary in this case?
I solved this problem by inflating the MainLayout on top of the rootLayout. I tried a similar solution to this before but I probably used "R.id.content" instead of "android.R.id.content".
This code belongs to the bottom of the onCreate method of the MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
// ...
setContentView(treeView.view)
val rootLayout = findViewById<FrameLayout>(android.R.id.content)
View.inflate(this, R.layout.main_layout, rootLayout)
}