Can't make ScrollView fill whole parent in a popup - android

I'm trying to make a help popup. Since the help tips will be different according to which screen you click the help button from, I want to put the text inside a scroll just in case. My layout looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/helpPopupTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:gravity="center"
android:text="#string/help_popup_title"
android:textColor="?attr/colorOnBackground"
android:textSize="24sp"
android:textStyle="bold" />
<ScrollView
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:fillViewport="true">
<TextView
android:id="#+id/helpTips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/help_tips"
android:textSize="20sp" />
</ScrollView>
<Button
android:id="#+id/footerButton"
style="#style/RoundedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="20dp"
android:text="#string/footer_button_text" />
It's basically a title, the scroll, and a button. My problem is, when the popup shows up, the scroll is just as tall as the text inside of it.
This is how it looks
This is how I build the dialog:
val dialogView = LayoutInflater.from(this).inflate(R.layout.help_popup, null)
val dialogBuilder = AlertDialog.Builder(this).setView(dialogView)
dialogView.findViewById<TextView>(R.id.helpPopupTitle).setText(R.string.help_popup_title)
dialogView.findViewById<TextView>(R.id.helpTips).setText(R.string.help_tips)
val dialog = dialogBuilder.create()
dialog.setCanceledOnTouchOutside(true)
dialogView.findViewById<Button>(R.id.footerButton).setOnClickListener {
dialog.dismiss()
}
dialog.show()
val displayMetrics = DisplayMetrics()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
val display = display
display?.getRealMetrics(displayMetrics)
} else {
#Suppress("DEPRECATION")
val display = windowManager.defaultDisplay
#Suppress("DEPRECATION")
display.getMetrics(displayMetrics)
}
val width = displayMetrics.widthPixels
val height = displayMetrics.heightPixels
val popupWidth = width * 0.9
val popupHeight = height * 0.85
dialog.window!!.setLayout(popupWidth.toInt(), popupHeight.toInt())
It is really messy, but so far it works since what I want is a popup that covers most of the screen but not entirely. I've looked in other threads but most just say "just put android:fillViewport="true" and the scroll will fill the parent" but it doesn't work for me, maybe I messed up something while building the popup. Any help?
EDIT: After trying the answer provided by gioravered the weight is actually working and the scroll fills the parent. The only problem is that now the layout is slightly offcentered.
Popup after the edit

Keep your LinearLayout, but add an ID for the root view (mainLayout):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/mainLayout"
android:orientation="vertical">
<TextView
android:id="#+id/helpPopupTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:gravity="center"
android:text="#string/help_popup_title"
android:textColor="?attr/colorOnBackground"
android:textSize="24sp"
android:textStyle="bold" />
<ScrollView
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:fillViewport="true">
<TextView
android:id="#+id/helpTips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/help_tips"
android:textSize="20sp" />
</ScrollView>
<Button
android:id="#+id/footerButton"
style="#style/RoundedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="20dp"
android:text="#string/footer_button_text" />
</LinearLayout>
What you did was changing the size of the dialog window.
Instead, let's change the size of the Layout itself.
val dialogView = LayoutInflater.from(this).inflate(R.layout.popup, null)
val dialogBuilder = AlertDialog.Builder(this).setView(dialogView)
val dialog = dialogBuilder.create()
dialog.setCanceledOnTouchOutside(true)
dialogView.findViewById<Button>(R.id.footerButton).setOnClickListener {
dialog.dismiss()
}
dialog.show()
val displayMetrics = DisplayMetrics()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
val display = display
display?.getRealMetrics(displayMetrics)
} else {
#Suppress("DEPRECATION")
val display = windowManager.defaultDisplay
#Suppress("DEPRECATION")
display.getMetrics(displayMetrics)
}
val screenWidth = displayMetrics.widthPixels
val screenHeight = displayMetrics.heightPixels
val popupWidth = screenWidth * 0.9
val popupHeight = screenHeight * 0.85
val mainLayout = dialogView.findViewById<LinearLayout>(R.id.mainLayout)
val params = (mainLayout.layoutParams as? FrameLayout.LayoutParams)?.apply {
width = popupWidth.toInt()
height = popupHeight.toInt()
gravity = Gravity.CENTER;
}
mainLayout.layoutParams = params
The change is this line:
dialogView.findViewById<LinearLayout>(R.id.mainLayout).layoutParams =
Since the layout is the parent layout it will determine the size of the dialog.

Related

How do I show an admob native ad in my App?

I have a single activity app with a navigation component. On my app, I am trying to implement an AdMob native ad (with a test unitId from google developer docs), but it doesn't show up no matter how much I've tried and I read this document but I didn't understand how am I gonna display it with there code. I also tried looking for examples and tutorials but most of them are in languages I don't understand. Any help would be appreciated!.
My manifast
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="#string/appId"/> // it is a sample
my_nativead.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="3dp"
android:background="#drawable/linear_border_style">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ad"
android:textColor="#color/white"
android:background="#color/blue"
android:backgroundTint="#color/blue"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/nativeAdSmallImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_email"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/nativeAdSmallTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginStart="10dp"
android:textStyle="bold"
android:textColor="#color/black"
android:text="Ad Title"/>
<com.google.android.gms.ads.nativead.MediaView
android:id="#+id/nativeAdSmallMedia"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/nativeAdSmallName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10sp"
android:layout_marginStart="10dp"
android:textColor="#color/black"
android:text="Ad description"/>
<TextView
android:id="#+id/nativeAdSmallDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp"
android:layout_marginStart="10dp"
android:textColor="#color/black"
android:text="Ad description"/>
<Button
android:id="#+id/nativeAdSmallButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="visit site"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
My mainActivity
frame = findViewById(R.id.myAd)
MobileAds.initialize(this)
val adBuilder = AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110") // the unitId is a sample
.forNativeAd { nativeAd ->
desplayNativeAd(frame, nativeAd)
}
adBuilder.build()
}
fun desplayNativeAd(parent: ViewGroup, ad: NativeAd){
val inflater = parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)
as LayoutInflater
val adView = inflater.inflate(R.layout.native_small_adview, parent) as NativeAdView
val headlineView = adView.findViewById<TextView>(R.id.nativeAdSmallTitle)
headlineView.text = ad.headline
adView.headlineView = headlineView
val advertiser = adView.findViewById<TextView>(R.id.nativeAdSmallName)
advertiser.text = ad.advertiser
adView.advertiserView = advertiser
val imageAdView = adView.findViewById<ImageView>(R.id.nativeAdSmallImage)
Glide.with(this)
.load(ad.icon)
.into(imageAdView)
val mediaView = adView.findViewById<MediaView>(R.id.nativeAdSmallMedia)
adView.mediaView = mediaView
adView.setNativeAd(ad)
parent.removeAllViews()
parent.addView(adView)
}
My mainActivity.xml // i have a lot of xml code on this one but I only showed this, this is a framelyout that spposed to handle the the native ads
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="#+id/myAd"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
I just solved it on my on, I only called the frame layout from my my main fragment instead of my main activity and I wrote the adBuilder with it's function in the fragment's onViewCreated method.
Here is what I wrote..
// I wrote it in onViewCreated meathod
MobileAds.initialize(requireContext())
//native ad
val adBuilder = AdLoader.Builder(requireContext(), "your_ad_id")
.forNativeAd { nativeAd ->
val adView = layoutInflater.inflate(R.layout.native_big_adiew, null) as NativeAdView
displayBigNativeAd(adView, nativeAd)
frame.removeAllViews()
frame.addView(adView)
}
.build()
adBuilder.loadAd(AdRequest.Builder().build())
// outside onViewCreated method
private fun displayBigNativeAd(adView: NativeAdView, ad: NativeAd) {
val headline = adView.findViewById<TextView>(R.id.nativeAdBigTitle)
headline.text = ad.headline
adView.headlineView = headline
val advertiser = adView.findViewById<TextView>(R.id.nativeAdBigName)
advertiser.text = ad.advertiser
adView.advertiserView = adView
val icon = adView.findViewById<ImageView>(R.id.nativeAdBigImage)
icon.setImageDrawable(ad.icon.drawable)
adView.iconView = icon
val mediaView = adView.findViewById<MediaView>(R.id.nativeAdBigMediaView)
adView.mediaView = mediaView
val button = adView.findViewById<Button>(R.id.nativeAdBigButton)
adView.callToActionView = button
button.setText(ad.store)
val body = adView.findViewById<TextView>(R.id.nativeAdBigDesc)
body.text = ad.body
adView.bodyView = body
val price = adView.findViewById<TextView>(R.id.nativeAdBigPrice)
price.text = ad.price
adView.priceView = price
adView.setNativeAd(ad)
}

Guidelines Inside ScrollView - use Viewport %

I would like to add content to an app that starts at about 70% down vertically and can be scrolled upwards to cover the top 70% views.
I thought of using two children ConstraintLayout's inside a parent ConstraintLayout - the two children would be on top of each other. One would contain the views that would populate the first 70% of the screen while the other would contain a NestedScrollView which has an invisible <View> that takes up 70% of the height and then the additional content that can be scrolled up.
I'm facing a problem with marking the 70% spot - using a Guideline inside the NestedScrollView isn't working because the %s are fluid (it matches to 70% of the content inside the NestedScrollView instead of 70% of the viewable screen). Using a Guideline outside the NestedScrollView doesn't work because well... constraints have to be siblings to compile.
How can I accomplish this?
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/firstConstraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/red5F"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
// A bunch of content that should fill up the first 70% of the screen and be covered by the overlay if user scrolls
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/overlayConstraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:fillViewport="true"
android:id="#+id/scrollView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/overlayInnerLayout">
<androidx.constraintlayout.widget.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/verticalGuidelineOverlay"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.7"/>
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/spacerView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/verticalGuidelineOverlay"
app:layout_constraintLeft_toLeftOf="parent"/>
// More content here that the user could scroll upwards that would start at the 70% point and eventually cover the entire screen.
</ConstraintLayout>
</NestedScrollView>
</ConstraintLayout>
</ConstraintLayout>
Video w/example here: https://imgur.com/a/BTolYUu
Try out this method,
<?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:id="#+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/firstConstraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/overlayConstraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.core.widget.NestedScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:orientation="horizontal">
<RelativeLayout
android:id="#+id/transparentView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="0.3" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20sp"
android:text="#string/lorem_ipsum"
tools:ignore="MissingConstraints"
android:textSize="18sp"/>
</RelativeLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
set 70% height programatically using layoutParams
val transparentView = findViewById<RelativeLayout>(R.id.transparentView)
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
val height = Math.min(metrics.widthPixels, metrics.heightPixels) //height
val params = transparentView.layoutParams
params.height = (height * 70) / 70
transparentView.layoutParams = params
you will get the required result : enter link description here
Remove guidelines and use a view like this as a spacer view. It's height constrained to be 1.15 of it's width. You can change it around a littile to get what you want
<View
android:id="#+id/spacerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1.15"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
Also just as an advice
you're not supposed to use match_parent in ConstraintLayout, use 0dp and constraint it to both sides.
Top layout can be replaced with FrameLayout, cause you don't really use any constraints
You can use a customized BottomSheetDialogFragment that has a theme of Theme_Translucent_NoTitleBar, and change the y value of the root layout of the dialog whenever the user drags it up or down.
class MyDialogFragment(height: Int) : BottomSheetDialogFragment(), View.OnTouchListener {
private val outsideWindowHeight = height
private val rootLayout by lazy {
requireView().findViewById<LinearLayout>(R.id.dialog_root)
}
private var oldY = 0
private var baseLayoutPosition = 0
private var defaultViewHeight = 0
private var isClosing = false
private var isScrollingUp = false
private var isScrollingDown = false
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return BottomSheetDialog(
requireContext(),
android.R.style.Theme_Translucent_NoTitleBar
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view: View = inflater.inflate(
R.layout.fragment_dialog, container,
false
)
view.setBackgroundResource(R.drawable.rounded_background)
(dialog as BottomSheetDialog).apply {
setCancelable(false)
behavior.peekHeight =
(outsideWindowHeight * 0.3).toInt() // Minimum height of the BottomSheet is 30% of the root layout (to leave the 70% to the main layout)
}
return view
}
#SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rootLayout.setOnTouchListener(this)
}
#SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
// Get finger position on screen
val y = event!!.rawY.toInt()
// Switch on motion event type
when (event.action and MotionEvent.ACTION_MASK) {
MotionEvent.ACTION_DOWN -> {
// save default base layout height
defaultViewHeight = rootLayout.height
oldY = y
baseLayoutPosition = rootLayout.y.toInt()
}
MotionEvent.ACTION_UP -> {
// If user was doing a scroll up
if (isScrollingUp) {
// Reset baselayout position
rootLayout.y = 0f
// We are not in scrolling up anymore
isScrollingUp = false
}
// If user was doing a scroll down
if (isScrollingDown) {
// Reset baselayout position
rootLayout.y = 0f
// Reset base layout size
rootLayout.layoutParams.height = defaultViewHeight
rootLayout.requestLayout()
// We are not in scrolling down anymore
isScrollingDown = false
}
}
MotionEvent.ACTION_MOVE -> {
if (rootLayout.y <= -100) {
return true
}
if (!isClosing) {
val currentYPosition = rootLayout.y.toInt()
// If we scroll up
if (oldY > y) {
// First time android rise an event for "up" move
if (!isScrollingUp) {
isScrollingUp = true
}
rootLayout.y = rootLayout.y + (y - oldY)
} else {
// First time android rise an event for "down" move
if (!isScrollingDown) {
isScrollingDown = true
}
// change position because view anchor is top left corner
rootLayout.y = rootLayout.y + (y - oldY)
rootLayout.requestLayout()
}
// Update position
oldY = y
}
}
}
return true
}
}
fragment_dialog.xml (Nothing fancy):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dialog_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tv_bottom_sheet_heading"
android:layout_width="wrap_content"
android:layout_height="#dimen/dp_56"
android:layout_marginStart="#dimen/dp_16"
android:layout_marginEnd="#dimen/dp_16"
android:gravity="center"
android:text="#string/bottom_sheet_option_heading"
android:textColor="#android:color/black"
android:textSize="16sp" />
<TextView
android:id="#+id/tv_btn_add_photo_camera"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_48"
android:layout_marginStart="#dimen/dp_16"
android:layout_marginEnd="#dimen/dp_16"
android:backgroundTint="#android:color/white"
android:drawableStart="#drawable/ic_camera_alt_black_24dp"
android:drawableLeft="#drawable/ic_camera_alt_black_24dp"
android:drawablePadding="#dimen/dp_32"
android:drawableTint="#color/md_bottom_sheet_text_color"
android:gravity="start|center_vertical"
android:text="#string/bottom_sheet_option_camera"
android:textColor="#color/md_bottom_sheet_text_color"
android:textSize="16sp" />
<TextView
android:id="#+id/tv_btn_add_photo_gallery"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="#dimen/dp_16"
android:layout_marginEnd="#dimen/dp_16"
android:backgroundTint="#android:color/white"
android:drawableStart="#drawable/ic_insert_photo_black_24dp"
android:drawableLeft="#drawable/ic_insert_photo_black_24dp"
android:drawablePadding="#dimen/dp_32"
android:drawableTint="#color/md_bottom_sheet_text_color"
android:gravity="start|center_vertical"
android:text="#string/bottom_sheet_option_gallery"
android:textColor="#color/md_bottom_sheet_text_color"
android:textSize="16sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="#dimen/md_bottom_sheet_separator_top_margin"
android:layout_marginBottom="#dimen/dp_8"
android:background="#color/grayTextColor" />
<TextView
android:id="#+id/tv_btn_remove_photo"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_48"
android:layout_marginStart="#dimen/dp_16"
android:layout_marginEnd="#dimen/dp_16"
android:backgroundTint="#android:color/white"
android:drawableStart="#drawable/ic_delete_black_24dp"
android:drawableLeft="#drawable/ic_delete_black_24dp"
android:drawablePadding="#dimen/dp_32"
android:drawableTint="#color/md_bottom_sheet_text_color"
android:gravity="start|center_vertical"
android:text="#string/bottom_sheet_option_remove_photo"
android:textColor="#color/md_bottom_sheet_text_color"
android:textSize="16sp" />
<com.google.android.material.button.MaterialButton
android:id="#+id/btn_material"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Material button"
android:textAppearance="#style/TextAppearance.AppCompat.Medium" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/longText1"
android:textColor="#color/white"
android:textSize="22sp" />
</LinearLayout>
And send the height of the root ViewGroup of the main layout to the dialog in the main activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val root = findViewById<ConstraintLayout>(R.id.root)
root.viewTreeObserver.addOnGlobalLayoutListener(object :
OnGlobalLayoutListener {
override fun onGlobalLayout() {
root.viewTreeObserver
.removeOnGlobalLayoutListener(this)
val dialogFragment = MyDialogFragment(root.height)
dialogFragment.show(supportFragmentManager, "dialog_tag")
}
})
}
}
Preview:

TextView doesn`t center newly inserted text

I have one textView in ScrollView, and it doesnt center text after inserting. I tried change properties later,in code section, but it was useless. Maybe its all because of Anco.
TextView resultdop is the one I was asking about. Other TextView, resultfield, works fine.
XML code:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAlignment="center"
android:layout_below="#id/result">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:orientation="horizontal">
<TextView
android:id="#+id/resultdop"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:gravity="center_horizontal"
android:textAlignment="center"
android:textColor="#color/white" />
</LinearLayout>
</ScrollView>
Code
if (resultdop.text == ""){
val city: String = userfield.text.toString()
val key = "e9c95bab1d070877909fd3e55310c60c"
val url = "https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$key&units=metric&lang=ru"
val urls = "https://api.openweathermap.org/data/2.5/forecast?q=$city&appid=$key&units=metric&lang=ru"
//val imm: InputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
//imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
doAsync {
val apiresponse = URL(url).readText()
val weather = JSONObject(apiresponse).getJSONArray("weather")
val desc = weather.getJSONObject(0).getString("description")
val main = JSONObject(apiresponse).getJSONObject("main")
val temp = main.getString("temp")
resultfield.text = "Температура: $temp ℃, $desc"
val apiresponses = URL(urls).readText()
val list = JSONObject(apiresponses).getJSONArray("list")
var otvet = ""
for (i in 1 until list.length()){
val obj = list.getJSONObject(i)
val tempd = obj.getJSONObject("main").getInt("temp")
val weatherd = obj.getJSONArray("weather")
val descd = weatherd.getJSONObject(0).getString(("description"))
val time = obj.getString("dt_txt")
otvet += "$time \n $tempd ℃, $descd \n \n"
}
resultdop.text = otvet
}
resultdop.gravity = Gravity.CENTER
resultdop.textAlignment = View.TEXT_ALIGNMENT_CENTER
resultdop.textAlignment = View.TEXT_ALIGNMENT_GRAVITY
}
Remove the android:textAlignment="center" from scroll view and linear layout. if the textView layout_width is match_parent then you can apply either android:textAlignment="center" or android:gravity="center" it will work.
<ScrollView android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/result"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/resultdop"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:textAlignment="center"
android:text="Hello World"
android:textColor="#color/white" />
</LinearLayout>
</ScrollView>
and Try Invalidate Cache/Restart Android studio

Unable to match parent the custom dialog's width

I am have created a custom dialog and defined the width as match_parent. But when I ran the application, it appears not even wrapping the content as most of the content is getting clipped. I tried some of the solutions but getting the same result, I have no idea what am I doing wrong:
dialog_messages.xml
<com.google.android.material.card.MaterialCardView
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"
android:orientation="vertical"
app:cardCornerRadius="#dimen/corner"
app:cardElevation="#dimen/elevation"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/ic_msg_sm"
android:drawablePadding="#dimen/normal"
android:drawableTint="#color/colorDanger"
android:padding="#dimen/normal_2x"
android:text="Send Message"
android:textColor="#color/colorBlack"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorGrey" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/normal_2x"
android:text="Tap a message to send"
android:textColor="#color/colorGrey"
android:textSize="#dimen/font_sm1" />
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/normal_2x" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="#color/colorGrey" />
<Button
android:id="#+id/btnCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="#dimen/normal"
android:background="#null"
android:paddingHorizontal="#dimen/normal_4x"
android:text="Cancel"
android:textColor="#color/colorDanger" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
and the setup class
MessageDialog.kt
class MessageDialog(
private val activity: Activity,
private val onMessageClickListener: MessageClickListener
) : Dialog(activity) {
private val messageList = arrayListOf<String>(
"Can't locate you. Send instructions",
"Heavy Traffic. I'll be late 10 minutes",
"Just turning around the block",
"Taxi arrived",
"I am coming to your location",
"I am arriving in 5 minutes",
"Ok"
)
private lateinit var listView: ListView
private lateinit var btnCancel: Button;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
setContentView(R.layout.dialog_messages)
val adapter = ArrayAdapter(activity, android.R.layout.simple_list_item_1, messageList)
listView = findViewById(R.id.listView)
listView.adapter = adapter
listView.setOnItemClickListener { parent, view, position, id ->
onMessageClickListener.onMessageClick(messageList.get(position))
dismiss()
}
btnCancel = findViewById(R.id.btnCancel)
btnCancel.setOnClickListener {
dismiss()
}
}
}
But this is the result:
I have tried some other answers already provided here, but nothing works.
Create a Dialog object and do this in the show() part.
val dialog = MessageDialog(activity, messageClickListener)
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window!!.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
dialog.show()
val window = dialog.window
window!!.attributes = lp
For my case, i was using afollestad material dialog library, and it had default margin. I overrided that margin on my dimens.xml file
<dimen name="md_dialog_horizontal_margin">8dp</dimen>
Here 8dp means, dialog both from left and right margin will be 16 dp so if you want margin to be 16dp type it as 8dp, divided by two :)

Changing width and height in ConstraintLayout programmatically doesn't work

I would like to change the following UI to be full screen programmatically.
<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/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<TextView
android:id="#+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ONE"
android:background="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="#+id/two"
/>
<TextView
android:id="#+id/two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TWO"
android:background="#android:color/holo_blue_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="#+id/one"
/>
</android.support.constraint.ConstraintLayout>
In my Kotlin file:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val param = ConstraintLayout.LayoutParams(0, 0)
one.layoutParams = param
two.layoutParams = param
}
}
Both TextView disappears after I set the width and height to 0 instead of being scratched fullscreen.
Desired UI
You're doing it wrong. You've to apply a new ConstraintSet like:
val constraintSet1 = ConstraintSet()
constraintSet1.clone(yourConstraintLayout)
val constraintSet2 = ConstraintSet()
constraintSet2.clone(yourConstraintLayout)
constraintSet2.constrainWidth(R.id.one, 0)
constraintSet2.constrainWidth(R.id.two, 0)
constraintSet2.constrainHeight(R.id.one, 0)
constraintSet2.constrainHeight(R.id.two, 0)
// to switch to full screen
constraintSet2.applyTo(yourConstraintLayout)
// to get back to your original screen
constraintSet1.applyTo(yourConstraintLayout)

Categories

Resources