How to set bottom margin to FAB in Anko DSL layout? - android

I use Anko DSL layout in my kotlin activity. I can not set bottom margin to FAB. Right margin work.
In my activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
(application as SamfantozziApp).dgaeacomponent().inject(this)
InvoiceListKtActivityUI(_rxBus).setContentView(this)
}
My Anko DSL layout InvoiceListKtActivityUI.kt
class InvoiceListKtActivityUI (val _rxBus: RxBus): AnkoComponent<InvoiceListKtActivity>{
override fun createView(ui: AnkoContext<InvoiceListKtActivity>): View = with(ui){
return relativeLayout{
padding = dip(5)
lparams {
width = matchParent
height = wrapContent
margin = 5
}
verticalLayout{
tabLayout{
lparams {
width = matchParent
height = wrapContent
}
id = R.id.tabs
}
viewPager{
lparams {
width = matchParent
height = matchParent
}
id = R.id.container
}
}
floatingActionButton{
lparams {
width = wrapContent
height = wrapContent
rightMargin = 40 //works
bottomMargin = 40 //does not work
alignParentBottom()
alignParentRight()
}
imageResource = android.R.drawable.ic_input_add
id = R.id.fabinvoice
onClick{
_rxBus.send(InvoiceListFragment.ClickFobEvent())
}
}
}
}
}

I think you are not setting the lparams correctly. The proper form is:
floatingActionButton {
imageResource = android.R.drawable.ic_input_add
}.lparams{
rightMargin = dip(16)
bottomMargin = dip(16)
alignParentBottom()
alignParentRight()
}

Related

Text Scaling seems to have no effect

private fun setQuestion() {
val mainImg = findViewById<ImageView>(R.id.movieImgView)
val movieNameText = findViewById<TextView>(R.id.movieName)
val movieYearText = findViewById<TextView>(R.id.movieYear)
val movieRatingText = findViewById<TextView>(R.id.movieRatingText)
val seriesOrNoText = findViewById<TextView>(R.id.seriesOrNoText)
val btnNext = findViewById<Button>(R.id.btnNext)
movieList = Constants.getActionMovies()
val movie: ActionMovies? = movieList!![currentPosition - 1]
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
val height = displayMetrics.heightPixels.toFloat()
val width = displayMetrics.widthPixels.toFloat()
mainImg.setImageResource(movie!!.moviePic)
movieNameText.text = movie.movieName
movieNameText.scaleX = width
movieNameText.scaleY = height
movieYearText.text = "(${movie.date.toString()})"
movieRatingText.text = movie.rating
if (movie.series) {
seriesOrNoText.text = "Yes"
} else {
seriesOrNoText.text = "No"
}
if (currentPosition == movieList!!.size) {
btnNext.text = "Return to \n Main Menu"
btnNext.setOnClickListener {
finish()
}
}
}
}
I'm trying to set the width and height of my MovieNameText, however it seems to have no effect at all, any help? I've defined the text size in the xml file to 30sp, I've tried setText and scaleX and textSize
To change the size of the text
movieNameText.textSize = 30f // or whatever value you would like to use
Aslong as your Textview is constrained and layout width and height is set to 'wrap content' it should scale with your app.

Android, set WRAP_CONTENT layout parameter of ImageView by code not working

This doesn't works as expected:
imageView = ImageView(context)
imageView.adjustViewBounds = true
imageView.scaleType = ImageView.ScaleType.FIT_CENTER
imageView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
imageView.setImageBitmap(myBitmap)
The imageView is added to a TableRow layout (which is added to a Table).
Full function:
fun loadTable(data: List<ListItem>) = lifecycleScope.launch {
val rowParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
val table = binding.table
val context = table.context
for (i in data.indices) {
val rowIndex = i / TABLE_COLUMNS
val row: TableRow = if (table.childCount <= rowIndex) {
val r = TableRow(context)
r.layoutParams = rowParams
binding.table.addView(r)
table.layoutParams.width = myBitmap.width * TABLE_COLUMNS
r
} else {
table[rowIndex] as TableRow
}
imageView = ImageView(context)
imageView.adjustViewBounds = true
imageView.scaleType = ImageView.ScaleType.FIT_CENTER
imageView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
imageView.setImageBitmap(myBitmap)
row.addView(imageView)
}
}
Expected result: the imageView display the image and has the same size.
Actual result: the imageView has a zero-size and image is not displayed.
With the layout inspector I can see that the attributes are correct, but the size of the imageView remains 0.0.
If I set the same attribute at design time, the imageView is displayed correctly.

How to get parent ConstraintLayout view to match its child TextView height programmatically

It's awesome to be learning ConstraintLayout and Kotlin. I have a constraintLayout popupView, which is the parent view of a TextView titleLabel. I'd like popupView height to adjust to the content of its child titleLabel TextView. titleLabel height can vary due to different text strings used.
Both titleLabel and popupView are set to WRAP_CONTENT for the height layout params, but the popupView isn't getting rendered. Adding a fixed height constraint to popupView's constraintSet will render it, but a fixed height will not work when titleLabel height changes.
Any ideas how to get it working? Here's what I have
open class PopupActivity(): AppCompatActivity() {
public var message:String = "This is a message string for the label"
val titleLabel: TextView by lazy {
val label = TextView(this)
label.gravity = Gravity.CENTER
label.setTextSize(Constants.FontSizePopupTitle)
return#lazy label
}
val popupView: ConstraintLayout by lazy {
val view = ConstraintLayout(this)
view.setBackgroundColor(Color.primary())
return#lazy view
}
val view: ConstraintLayout by lazy {
val v = ConstraintLayout(this)
return#lazy v
}
#SuppressLint("ResourceType")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
view.id = 1
popupView.id = 2
titleLabel.id = 5
var margin = 2 * Constants.SpacingStandard.toInt()
view.addView(popupView)
popupView.addView(titleLabel)
titleLabel.layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
ConstraintLayout.LayoutParams.WRAP_CONTENT)
titleLabel.text = message
popupView.layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
ConstraintLayout.LayoutParams.WRAP_CONTENT)
val popupConstraintSet = ConstraintSet()
popupConstraintSet.connect(popupView.id, START, view.id, START, margin)
popupConstraintSet.connect(popupView.id, END, view.id, END, margin)
popupConstraintSet.centerHorizontally(popupView.id, view.id)
popupConstraintSet.centerVertically(popupView.id, view.id)
view.setConstraintSet(popupConstraintSet)
setContentView(view)
}
}
You can fix this by switching the order of the view#id in the connect functions
popupConstraintSet.connect(view.id, START, popupView.id, START, margin)
popupConstraintSet.connect(view.id, END, popupView.id, END, margin)
popupConstraintSet.centerHorizontally(view.id, popupView.id)
popupConstraintSet.centerVertically(view.id, popupView.id)
OR set the ConstraintSet to the popUpView. The field already has the correct name ^^
popUpView.setConstraintSet(popupConstraintSet)
Here's what I ended up doing:
remove popupView.layoutParams; WRAP_CONTENT for height seems to be ignored...
add constrainHeight with WRAP_CONTENT to constraintSet
onCreate is now this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
view.id = 1
popupView.id = 2
titleLabel.id = 5
popupView.addView(titleLabel)
view.addView(popupView)
titleLabel.layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
ConstraintLayout.LayoutParams.WRAP_CONTENT)
titleLabel.text = message
var margin = 2 * Constants.SpacingStandard.toInt()
val popupConstraintSet = ConstraintSet()
popupConstraintSet.connect(popupView.id, START, view.id, START, margin)
popupConstraintSet.connect(popupView.id, END, view.id, END, margin)
popupConstraintSet.constrainHeight(popupView.id, ConstraintSet.WRAP_CONTENT)
popupConstraintSet.centerHorizontally(popupView.id, view.id)
popupConstraintSet.centerVertically(popupView.id, view.id)
view.setConstraintSet(popupConstraintSet)
setContentView(view)
}
}

Setting maximum expanded height for bottomsheet dynamically

How to set maximum expanded height in android support design bottom sheet?
The question is an extension to the above question, i want to set the max expanded height of the sheet but dynamically according to the screen size.
I have tried setting new layout params to the view implementing bottomsheet behaviour but it does nothing good.
Please use this and chill :)
const val BOTTOMSHEET_HEIGHT_TO_SCREEN_HEIGHT_RATIO = 0.80 //change according to your requirement
override onCreateDialog() in your bottomsheetFragment
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
dialog.setOnShowListener {
dialog.findViewById<FrameLayout>(com.google.android.material.R.id.design_bottom_sheet)
?.apply {
val maxDesiredHeight =
(resources.displayMetrics.heightPixels * BOTTOMSHEET_HEIGHT_TO_SCREEN_HEIGHT_RATIO).toInt()
if (this.height > maxDesiredHeight) {
val bottomSheetLayoutParams = this.layoutParams
bottomSheetLayoutParams.height = maxDesiredHeight
this.layoutParams = bottomSheetLayoutParams
}
BottomSheetBehavior.from(this)?.apply {
this.state = BottomSheetBehavior.STATE_EXPANDED
this.skipCollapsed = true
}
}
}
return dialog
}
2021
I'm late but someone will need
Kotlin extenxion:
fun View.setupFullHeight(maxHeight: Double = 0.3) {
val displayMetrics = context?.resources?.displayMetrics
val height = displayMetrics?.heightPixels
val maximalHeight = (height?.times(maxHeight))?.toInt()
val layoutParams = this.layoutParams
maximalHeight?.let {
layoutParams.height = it
}
this.layoutParams = layoutParams
}
How to use:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return object : BottomSheetDialog(requireContext(), R.style.DialogRoundedCornerStyle) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dialog?.setOnShowListener {
val bottomSheetDialog = it as BottomSheetDialog
val parentLayout =
bottomSheetDialog.findViewById<View>(R.id.design_bottom_sheet)
parentLayout?.let { view ->
val behavior = BottomSheetBehavior.from(view)
view.setupFullHeight()
behavior.apply {
state = BottomSheetBehavior.STATE_EXPANDED
isDraggable = false
isCancelable = false
}
}
}
}
override fun onBackPressed() {
super.onBackPressed()
dialog?.dismiss()
}
}
}
The simplest solution is to set the maxHeight property of the bottom sheet like this.
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
bottomSheet.setMaxHeight((int) (displayMetrics.heightPixels * 0.65));
Finally found it,
This question troubled me a lot with no solution reported anywhere, and the answer lies in the behavior itself.
The minimum offset is the max value upto which the bottomsheet should move and we set the lower cap of the value to our desired height upto which we want the bottomsheet to move.
You can expose a function to set the value or do it direclty in our behavior.
To dynamically set the max expanded height for bottomsheet we need to increase the minimum offset value from 0 to our desired value in BottomSheetBehavior class, let me show the code.
Happy coding!!
// The minimum offset value upto which your bottomsheet to move
private int mMinOffset;
/**
* Called when the parent CoordinatorLayout is about the layout the given child view.
*/
#Override
public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
int dynamicHeight = Utils.dpToPx(parent.getContext(), **your_value_in_dp**);
mMinOffset = Math.max(dynamicHeight, mParentHeight - child.getHeight());
mMaxOffset = Math.max(mParentHeight - mPeekHeight, mMinOffset);
mAnchorOffset = Math.min(mParentHeight - mAnchorHeight, mMaxOffset);
if (mState == STATE_EXPANDED) {
ViewCompat.offsetTopAndBottom(child, mMinOffset);
anchorViews(mMinOffset);
}
}

Setting height and width of an Anko view to match_parent

I would like to set the height and width of an video view to match_parent. My code looks something like the following. It works without the height and width attributes, but doing it as below give me a val cannot be reassigned error.
class VideoActivityUI : AnkoComponent<VideoActivity> {
companion object {
val ID_VIDEO = 11
}
override fun createView(ui: AnkoContext<VideoActivity>) = with(ui) {
videoView{
id = ID_VIDEO
height = matchParent
width = matchParent
}
}
}
You have to use lparams to set layout parameters, like this (you can omit the explicit parameter names if you want to):
videoView {
id = ID_VIDEO
}.lparams (width = matchParent, height = matchParent)
Alternatively, you can do it like this:
videoView {
id = ID_VIDEO
}.lparams {
height = matchParent
width = matchParent
}
The related wiki section for Anko can be found here.
Note that you have to have a ViewGroup around your VideoView as the root of the Activity's layout for it to have layout parameters available, because it gets different ones depending on whether it's in a FrameLayout, LinearLayout, or RelativeLayout.
For example, with a simple frameLayout, your code would look like this:
override fun createView(ui: AnkoContext<VideoActivity>) = with(ui) {
frameLayout {
videoView {
id = ID_VIDEO
}.lparams(matchParent, matchParent)
}
}

Categories

Resources