How to use View Binding with Linear Layout? - android

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

Related

in a kotlin can't get text from Textview in for loop

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.

Android - ActivityMainBinding shows me wrong activity

everyone. I'm trying to display a line chart in a full-screen activity. Unfortunately I can't do that. I always get to see my activity_main.xml layout. I also have my LineChart in it, within a CardView. Everything works fine in this activity. But as soon as I switch to activity_details_vitali.xml via a button, I don't see a line chart, just my main_activity. I think I have a wrong binding here. However, I can't find the error
class DetailsVitali : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_details_vitali)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setLineChartData()
}
private fun setLineChartData() {
val linevalues = ArrayList<Entry>()
linevalues.add(Entry(20f, 0.0F))
linevalues.add(Entry(30f, 3.0F))
linevalues.add(Entry(40f, 2.0F))
linevalues.add(Entry(50f, 1.0F))
linevalues.add(Entry(60f, 8.0F))
linevalues.add(Entry(70f, 10.0F))
linevalues.add(Entry(80f, 1.0F))
linevalues.add(Entry(90f, 2.0F))
linevalues.add(Entry(100f, 5.0F))
linevalues.add(Entry(110f, 1.0F))
linevalues.add(Entry(120f, 20.0F))
linevalues.add(Entry(130f, 40.0F))
linevalues.add(Entry(140f, 50.0F))
val linedataset = LineDataSet(linevalues, "First")
//We add features to our chart
linedataset.color = resources.getColor(R.color.purple_200)
linedataset.circleRadius = 5f
linedataset.setDrawFilled(true)
linedataset.valueTextSize = 10F
linedataset.fillColor = resources.getColor(R.color.purple_500)
linedataset.setMode(LineDataSet.Mode.CUBIC_BEZIER);
//We connect our data to the UI Screen
val data = LineData(linedataset)
binding.getTheGraph.data = data
binding.getTheGraph.setBackgroundColor(resources.getColor(R.color.white))
binding.getTheGraph.animateXY(2000, 2000, Easing.EaseInCubic)
}
layout
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".DetailsVitali">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
app:cardCornerRadius="10dp"
android:elevation="20dp"
android:layout_gravity="center_horizontal">
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/graphDetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.cardview.widget.CardView>
</LinearLayout>
</LinearLayout>
EDIT
And I also don't have access to the ID of my LineChart in the DetailsVitali.class. binding.ID.data = data is the ID is from the activity_main.xml.
From your comment that your desired layout is defined in activity_details_vitali.xml, you should be loading ActivityDetailsVitaliBinding, not ActivityMainBinding.
And as mentioned by #ARiF, you can remove the first call to setContentView since you are overwriting it with the second call to setContentView.

Android Kotlin - viewBinding Type mismatch: inferred type is DrawerLayout but ConstraintLayout was expected

I'm trying to get viewBinding to work.
This is the code:
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view: ConstraintLayout = binding.root
setContentView(view)
}
I manually declared the type ConstraintLayout because it's what I'm using for that activity called AskProfileImage:
<?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="#303030"
tools:context=".AskProfileImage">
<ImageView
android:id="#+id/imageView97545"
android:layout_width="108dp"
android:layout_height="64dp"
android:layout_marginTop="8dp"
android:background="#00FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/logo2" />
But I'm getting the error
Type mismatch: inferred type is DrawerLayout but ConstraintLayout was expected
on
binding.root
how to fix this?
viewBinding creates a class for each activity. So in my case for this activity it's:
ActivityAskProfileImageBinding
So the correct code is:
private lateinit var binding: ActivityAskProfileImageBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAskProfileImageBinding.inflate(layoutInflater)
setContentView(binding.root)
}
Since viewBinding is probably broadly used now, I don't understand why the hell nobody could answer that and why google docs are as always useless

BottomSheetDialogFragment is not showing up

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")

Android place view (TreeView) on top of MainLayout

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)
}

Categories

Resources