I created a custom dialog fragment but the width is very narrow. How can I increase it? I thought by setting width to 800dp, the dialog layout would wrap the content, but it constrains it within its default width.
Here is what I am looking for:
My 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="800dp"
android:layout_height="match_parent"
android:layout_gravity="center">
<com.google.android.material.button.MaterialButton
android:id="#+id/cancel_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/cancel"
android:paddingVertical="#dimen/keyline_6"
app:icon="#drawable/ic_arrow_back_black_24dp"
style="#style/MyTheme.Button.TextButton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="#id/terms_condition_header"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/terms_condition_header"
android:padding="#dimen/keyline_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Terms And Conditions"
android:textColor="#color/color_terms_condition_header"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cancel_btn"
android:textAppearance="#style/TextAppearance.MyTheme.Subtitle1"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/appCompatTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/keyline_6"
android:textColor="#color/color_terms_condition_header"
android:text="WHAT DRIVES US? Changing up your all-day, every-day, fun-day experience and having a good time doing it."
android:textAppearance="#style/TextAppearance.MyTheme.Subtitle2"
app:layout_constraintBottom_toTopOf="#+id/appCompatTextView2"
app:layout_constraintTop_toBottomOf="#id/terms_condition_header"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/appCompatTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingVertical="#dimen/keyline_4"
android:paddingLeft="#dimen/keyline_6"
android:text="Please read, respect and acknowledge the policies listed below:"
android:textAppearance="#style/TextAppearance.MyTheme.Subtitle3"
app:layout_constraintBottom_toTopOf="#+id/terms_condition_container"
app:layout_constraintTop_toBottomOf="#+id/appCompatTextView"
app:layout_constraintStart_toStartOf="parent"/>
<FrameLayout
android:id="#+id/terms_condition_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingLeft="#dimen/keyline_6"
app:layout_constraintTop_toBottomOf="#id/appCompatTextView2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<include layout="#layout/terms_condition_text"/>
</FrameLayout>
<com.google.android.material.button.MaterialButton
android:id="#+id/accept_terms_button"
style="#style/MyTheme.Button.Secondary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#color/color_secondary"
android:text="Accept Terms And Conditions"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/terms_condition_container" />
</androidx.constraintlayout.widget.ConstraintLayout>
Dialog class:
class TermsAndConditionDialogFragment : BaseDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.dialog_terms_condition, container, false)
return view
}
}
My preview:
Thanks in advance for any help!
Try this
#Override
public void onStart() {
super.onStart();
if (getContext() == null) return;
getDialog().getWindow().setLayout(((int) (0.8 * ScreenUtils.getScreenWidth(getContext()))), ViewGroup.LayoutParams.WRAP_CONTENT);
}
and this for getScreenWidth
public static int getScreenWidth(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(dm);
return dm.widthPixels;
}
Related
How to make Scrollview automatically scroll to the bottom when RadioButton is clicked
May I know How to make the Scroll view automatically scroll down to the next_button when any of the Radio Button is clicked ,
in the same time I need to call "setMeal() method from the ViewModel when the Radio Button is clicked.
<?xml version="1.0" encoding="utf-8"?>
<layout 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"
tools:context=".ui.MainMeal">
<data>
<variable
name="viewModel"
type="com.example.mymeal.model.OrderViewModel" />
<variable
name="mainMeal"
type="com.example.mymeal.ui.MainMeal" />
</data>
<ScrollView
android:layout_width="match_parent"
android:id="#+id/scrollView"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp">
<com.google.android.material.card.MaterialCardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
app:layout_constraintBottom_toTopOf="#+id/divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RadioGroup
android:id="#+id/main_meal_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RadioButton
android:id="#+id/royal_lobster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='#{viewModel.menuItems["royal butter lobster"].name}'
android:onClick='#{() -> viewModel.setMeal("royal butter lobster")}'
android:textAppearance="?attr/textAppearanceBody1"
tools:text="Royal Butter Lobster" />
<com.google.android.material.imageview.ShapeableImageView
android:id="#+id/royal_lobster_image"
android:layout_width="match_parent"
android:layout_height="194dp"
android:layout_margin="8dp"
app:shapeAppearanceOverlay="#style/cut_corner"
app:srcCompat="#drawable/royal_butter_lobster" />
<TextView
android:id="#+id/royal_lobster_description"
style="#style/Widget.MenuItem.TextView.Info"
android:text='#{viewModel.menuItems["royal butter lobster"].description}'
tools:text="Entree 3 description" />
<TextView
android:id="#+id/royal_lobster_price"
style="#style/Widget.MenuItem.TextView.Info"
android:paddingTop="8dp"
android:text='#{viewModel.menuItems["royal butter
lobster"].getFormattedPrice()}'
tools:text="$0.00" />
<View
style="#style/Widget.MyMeal.Divider"
android:layout_width="match_parent"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/royal_lobster_description" />
<RadioButton
android:id="#+id/kebbeh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='#{viewModel.menuItems["kebbeh"].name}'
android:onClick='#{() -> viewModel.setMeal("kebbeh")}'
android:textAppearance="?attr/textAppearanceBody1"
tools:text="Kebbeh" />
<com.google.android.material.imageview.ShapeableImageView
android:id="#+id/kebbeh_image"
android:layout_width="match_parent"
android:layout_height="194dp"
android:layout_margin="8dp"
app:shapeAppearanceOverlay="#style/cut_corner"
app:srcCompat="#drawable/kebbeh" />
<TextView
android:id="#+id/kebbeh_description"
style="#style/Widget.MenuItem.TextView.Info"
android:text='#{viewModel.menuItems["kebbeh"].description}'
tools:text="Entree 4 description" />
<TextView
android:id="#+id/kebbeh_price"
style="#style/Widget.MenuItem.TextView.Info"
android:paddingTop="8dp"
android:text='#{viewModel.menuItems["kebbeh"].getFormattedPrice()}'
tools:text="$0.00" />
<View
style="#style/Widget.MyMeal.Divider"
android:layout_width="match_parent"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/kebbeh_description" />
<RadioButton
android:id="#+id/shish_tawook"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='#{viewModel.menuItems["shish tawook"].name}'
android:onClick='#{() -> viewModel.setMeal("shish tawook")}'
android:textAppearance="?attr/textAppearanceBody1"
tools:text="Shish Tawook" />
<com.google.android.material.imageview.ShapeableImageView
android:id="#+id/shish_tawook_image"
android:layout_width="match_parent"
android:layout_height="194dp"
android:layout_margin="8dp"
app:shapeAppearanceOverlay="#style/cut_corner"
app:srcCompat="#drawable/shish_tawook" />
<TextView
android:id="#+id/shish_tawook_description"
style="#style/Widget.MenuItem.TextView.Info"
android:text='#{viewModel.menuItems["shish tawook"].description}'
tools:text="Entree 4 description" />
<TextView
android:id="#+id/shish_tawook_price"
style="#style/Widget.MenuItem.TextView.Info"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text='#{viewModel.menuItems["shish tawook"].getFormattedPrice()}'
tools:text="$0.00" />
</RadioGroup>
</com.google.android.material.card.MaterialCardView>
<View
android:id="#+id/divider"
style="#style/Widget.MyMeal.Divider"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cardView" />
<TextView
android:id="#+id/subtotal"
style="#style/Widget.MyMeal.TextView.Subtotal"
android:text='#{#string/subtotal(viewModel.subtotal)}'
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/divider"
tools:text="Subtotal $5.00" />
<Button
android:id="#+id/next_button"
style="#style/Widget.Order.Button.Next"
android:onClick="#{()-> mainMeal.goToNextFragment()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/cancel_button"
app:layout_constraintTop_toBottomOf="#id/subtotal" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>
This is the fragment class file
package com.example.mymeal.ui
class MainMeal : Fragment() {
// Binding object instance corresponding to the fragment_main_meal.xml layout.
private var _binding: FragmentMainMealBinding? = null
private val binding get() = _binding!!
//Get instance of OrderViewModel
private val sharedViewModel: OrderViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentMainMealBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = sharedViewModel
binding.mainMeal = this
}
//Navigate to the salad menu fragment
fun goToNextFragment() {
findNavController().navigate(R.id.action_mainMeal_to_saladMenu)
}
//Cancel the order
private fun cancelOrder() {
//Reset the values
sharedViewModel.resetOrder()
//Navigate back to the start fragment
findNavController().navigate(R.id.action_mainMeal_to_startFragment)
}
private fun doNothing() {
return
}
//confirmation before cancel the order
fun showDialog() {
MaterialAlertDialogBuilder(requireContext()).setMessage(getString(R.string.cancel_order))
.setCancelable(true)
.setNegativeButton(getString(R.string.yes)) { _, _ -> cancelOrder() }
.setPositiveButton(getString(R.string.no)) { _, _ -> doNothing() }.show()
}
/**
Clear out the binding object when the view hierarchy associated with the fragment
is being removed
*/
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Use the below code when the radio button is checked
scrollView.post(new Runnable() {
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
Try this:
fun scrollToViewBottom(scrollView: ScrollView, childView: View) {
val delay: Long = 500 //delay to let finish with possible modifications to ScrollView
scrollView.postDelayed({ scrollView.smoothScrollTo(0, childView.bottom) }, delay)
}
Call the function:
radioButton.setOnClickListener {
if (radioButton.isChecked) {
println("checked")
scrollToViewBottom(ScrollViewExplore, Mypage)
}
}
I've followed some previous questions and I've even solved this issue in some other projects, but for some reason I can't solve it here.
I have an app which creates "tasks" and creates a countdown for each one.
I have a view model with a list, and its observable via LiveData
val tasksList = mutableListOf<Task>()
private val _tasksListData = MutableLiveData(tasksList)
val tasksListData : LiveData<MutableList<Task>>
get() = _tasksListData
fun addNewTask(task : Task){
tasksList.add(task)
_tasksListData.value = tasksList
}
I have already check that the items are created via a log statement. So that's working alright.
Then in the fragment I'm observing this live data and trying to add dynamically each tag, but for some reason these are not shown:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_history,
container,
false
)
taskListContainer = binding.tasksListContainer
tasksViewModel = ViewModelProvider(requireActivity()).get(TasksViewModel::class.java)
//Checks if the list has some items, otherwise displays a message
checkTasksList()
tasksViewModel.tasksListData.observe(viewLifecycleOwner,{
for (item in it) {
val view: IndividualTaskViewBinding = DataBindingUtil.inflate(
inflater, R.layout.individual_task_view, container, false
)
view.taskTitle.text = item.name
view.taskDateCreated.text = item.dateCreated
view.taskTertiaryText.text = item.cyclesCompleted.toString()
taskListContainer.addView(view.root)
}
checkTasksList()
})
setHasOptionsMenu(true)
return binding.root
}
private fun checkTasksList(){
if(taskListContainer.childCount == 0 ){
binding.emptyListText.setVisibility(View.VISIBLE)
} else{
binding.emptyListText.setVisibility(View.GONE)
}
}
}
Here's the layout for each individual task:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:minHeight="88dp">
<ImageView
android:id="#+id/task_item_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentStart="true"
android:paddingTop="8dp"
app:srcCompat="#drawable/tomato" />
<TextView
android:id="#+id/task_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_toEndOf="#id/task_item_icon"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:maxLines="1"
tools:text="Title"
android:textAppearance="?attr/textAppearanceSubtitle1"
/>
<TextView
android:id="#+id/task_date_created"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/task_title"
android:layout_gravity="center_vertical"
android:layout_toEndOf="#id/task_item_icon"
android:paddingEnd="16dp"
android:maxLines="1"
tools:text="Date created"
android:textAppearance="?attr/textAppearanceBody2"
/>
<TextView
android:id="#+id/task_tertiary_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/task_date_created"
android:layout_gravity="center_vertical"
android:layout_toEndOf="#id/task_item_icon"
android:paddingEnd="16dp"
android:maxLines="1"
tools:text="task_tertiary_text"
android:textAppearance="?attr/textAppearanceBody2"
/>
</RelativeLayout>
</layout>
And here's the layour of the fragment:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".FragmentHistory">
<!-- using constraint layout so I can have the views floating in the screen-->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/empty_list_text"
style="#style/TextAppearance.MaterialComponents.Body1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/list_empty_text"
android:textAlignment="center"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="#+id/scrollView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/scrollView" />
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
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_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0">
<LinearLayout
android:id="#+id/tasks_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
As I mentioned before, the tasks are added to the list correclty, and the LiveData is also updated everytime a new task is added. But then the observer is not working, or the problem is when the layout is inflated.
Thank you very much for your help.
The entire project is here: https://github.com/arieldipietro/PomodoroTechnique
I just found that the problem is with the observer so I'm posting a new question Adding an Observer in a Tabbed Activity
So I'm fairly new to Kotlin.
I am trying to create an onClickListener on an image button to open the share interface, so that the particular video from the recyclerView can be shared via SMS, etc.
I followed various tutorials on how to do this as I am trying to execute this within a fragment, and the app just keeps crashing when I try to open the fragment in question.
I get the following error
java.lang.ClassCastException: java.lang.Integer cannot be cast to android.widget.ImageButton
Here is what my fragment code looks like:
SearchFragment.kt
class SearchFragment : Fragment(), View.OnClickListener
{
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<ClipAdapter.ViewHolder>? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View
{
val rootView = inflater.inflate(R.layout.fragment_search, container, false)
loadData()
return rootView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
val shareBtn = view.findViewById<ImageButton>(R.id.button_to_share)
shareBtn.setOnClickListener(this)
}
private fun loadData()
{
val service = TwitchServiceBuilder.buildService(TwitchService::class.java)
val requestCall = service.getClips("anerdfails")
requestCall.enqueue(object : Callback<List<Clip>>
{
override fun onResponse(
call: Call<List<Clip>>,
response: Response<List<Clip>>
)
{
if (response.isSuccessful)
{
//process data
recyclerView.layoutManager = GridLayoutManager(activity, 2)
recyclerView.adapter = ClipAdapter(response.body()!!)
} else
{
//output alert
AlertDialog.Builder(activity!!)
.setTitle("API error")
.setMessage("Response, but something went wrong ${response.message()}")
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
}
override fun onFailure(call: Call<List<Clip>>, t: Throwable)
{
//process failure
AlertDialog.Builder(activity!!)
.setTitle("API error")
.setMessage("No response, and something went wrong $t")
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
})
}
override fun onClick(v: View?)
{
Toast.makeText(activity, "Its toast!", Toast.LENGTH_SHORT).show()
}
}
And here are my 2 layouts for the RecyclerView:
fragment_search.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="15dp"
android:paddingTop="?attr/actionBarSize"
android:paddingEnd="15dp"
tools:context=".ui.search.SearchFragment">
<androidx.appcompat.widget.SearchView
android:background="#drawable/search_bar"
android:id="#+id/clipSearch"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="5dp"
android:focusable="true"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toTopOf="#+id/recyclerView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="75dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/clipSearch" />
</androidx.constraintlayout.widget.ConstraintLayout>
clip_layout.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.search.SearchFragment">
<VideoView
android:id="#+id/videoClip"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintDimensionRatio="w,2:3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txtTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videoClip"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtChannel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtTitle"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtGame"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtChannel"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtGame"
tools:ignore="HardcodedText" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:orientation="horizontal"
android:weightSum="2"
android:layout_marginTop="15dp"
app:layout_constraintTop_toBottomOf="#+id/txtViews">
<ImageButton
android:id="#+id/favouriteButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#null"
android:scaleType="fitCenter"
android:src="#drawable/ic_baseline_favorite_border_24" />
<ImageButton
android:id="#+id/button_to_share"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#null"
android:scaleType="fitCenter"
android:src="#drawable/ic_baseline_share_24" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Seems like a simple mistake on my part, but I'm pulling my hair out trying to work out what I've done wrong to cause the error on loading.
Any help would be appreciated.
I see you're trying to find the button "ShareBtn" inside the fragment which is totally wrong.
the "ShareBtn" doesn't belong to the fragment, it belongs to the viewHolder which you have created inside "ClipAdapter"
What you need to do is creating an interface inside "ClipAdapter" and create an object from it inside the Adapter
then call the method which is should the clickListener delegates the click to it
lastly, you should implement it inside the fragment and put whatever logic you want
This link will help you implement it
You are casting ID of view which is an Integer to ImageButton which is a View in this line
val shareBtn = R.id.button_to_share as ImageButton
You should use this instead
val shareBtn = findViewById<ImageButton>(R.id.button_to_share)
UPDATE
Also you should find views after fragment view got created. It means you should call `findViewById` inside `onViewCreated` and not inside `onCreateView`. If you try to find views before view of fragment gets created then you get `NullPointerException` since there is no view yet.
I'm adding new fragments dynamically to an existing fragment and I'm doing some calculation to infer the size of the new fragment.
After getting the new size i change the layout params of that new fragment to match the calculated size and this is where all the child views disappear - if i will not change the size the view will be presented perfectly ok.
XML code for the generated fragment:
<?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/playerCard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#339CEF"
android:clickable="true"
android:focusable="true"
tools:context=".playerCard">
<ImageView
android:id="#+id/playerImage"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="20dp"
android:layout_marginTop="40dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#DA4444"
android:clickable="false"
android:contentDescription="TODO"
android:focusable="true"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="#id/textView4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="#drawable/ic_menu_camera"
tools:srcCompat="#drawable/ic_menu_camera" />
<TextView
android:id="#+id/textView4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:background="#color/teal_200"
android:clickable="false"
android:focusable="true"
android:text="TextView"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/playerImage" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#99A9D8"
android:clickable="false"
android:contentDescription="TODO"
android:focusable="true"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is how i change the size on the card onCreateView (sizes were checked and are ok - not zero):
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
var view = inflater.inflate(R.layout.fragment_player_card, container, false)
view.x = this.centerPoint?.x?.toFloat() ?: 0.0f
view.y = this.centerPoint?.y?.toFloat() ?: 0.0f
view.layoutParams.width = this.cardSize?.width ?: 0
view.layoutParams.height = this.cardSize?.height ?: 0
view.requestLayout()
view.setOnTouchListener { v, event ->
onCardTouch(event)
}
return view
}
Also tried to do the size changing in a post statement but got the same results.
Any help will be appreciated.
Please use this solution here:
#Override
public void onResume() {
super.onResume();
getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) getLayoutParameters());
}
private final ViewGroup.LayoutParams getLayoutParameters(){
ViewGroup.LayoutParams layoutParameters = getDialog().getWindow().getAttributes();
layoutParameters.width = MYCALCULATEDSIZE.Width;
layoutParameters.height = MYCALCULATEDSIZE.Height;
return layoutParameters;
}
It's important to make sure that the layout parameters are updated when the Fragment Resumes, otherwise you could risk an exception, where the view has not been inflated yet.
Writing it here, makes sure that the fragment, along with its child views have been inflated properly.
I'm looking for a way to recreate the alert dialog in the Setting application of Android Wear:
Which is swipe to dismissable.
But instead, what I got is this:
Just a barebone Android dialog. How can I show the AlertDialog in the Settings.apk style? (Which I think must be default for Android Wear application)
I found no default way to do this, also setting a custom view to an AlertDialog did not look good. You can still try though, maybe a different Theme works.
What I did was create a new Activity and create my own layout which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout
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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
app:layout_box="all">
<TextView
android:id="#+id/tv_longtext"
android:layout_width="match_parent"
android:layout_height="0sp"
android:layout_weight="1"
android:fontFamily="sans-serif-condensed"
android:gravity="bottom"
android:padding="5sp"
android:text="Ambient screen reduces battery life."
android:textSize="16sp" />
<TextView
android:id="#+id/tv_question"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed"
android:gravity="center_horizontal|top"
android:paddingBottom="15sp"
android:paddingTop="5sp"
android:text="Turn on?"
android:textSize="18sp" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5sp">
<android.support.wearable.view.CircledImageView
android:id="#+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:src="#drawable/ic_cross"
app:circle_color="#AFAFAF"
app:circle_radius="25dp"
app:circle_radius_pressed="20dp" />
<android.support.wearable.view.CircledImageView
android:id="#+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:src="#drawable/ic_tick"
app:circle_color="#0EB695"
app:circle_radius="25dp"
app:circle_radius_pressed="20dp" />
</FrameLayout>
</LinearLayout>
</android.support.wearable.view.BoxInsetLayout>
It looks just like the confirmation screen from the settings. Maybe it still needs some tweaks, but I think this is the way to go.
I had a similar problem and indeed I didn't find a default way to do this. I tried to use AlertDialogs for WearOs and they don't look well, because even if you pass them a custom view, the AlertDialog class crops the layout in some unexpected ways.
How I ended up solving the problem is using the Dialog class (AlertDialog's parent class) and passing it a custom view. The Dialog class doesn't alter the layout and you can attach the dialog to an activity's lifespan (which is the idea of dialogs, creating a custom activity doesn't fit with this requirement).
So you could create a function like this inside your activity:
private void showDialog() {
Dialog dialog = new Dialog(this);
View myLayout = getLayoutInflater().inflate(R.layout.my_layout_id, null);
Button positiveButton = myLayout.findViewById(R.id.positive_button);
positiveButton.setOnClickListener(
v -> {
/* Your action on positive button clicked. */
}
);
Button negativeButton = myLayout.findViewById(R.id.negative_button);
negativeButton.setOnClickListener(
v -> {
/* Your action on negative button clicked. */
}
);
dialog.setContentView(myLayout);
dialog.show();
}
I created a similar fragment with custom layout like this:
Kotlin code:
/**
* Created by nmbinh87#gmail.com on 4/12/21.
*/
class ConfirmationDialog private constructor() : DialogFragment(R.layout.confirmation_dialog) {
var listener: Listener? = null
var longMessage: String = ""
var shortMessage = ""
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tv_longtext.text = longMessage
tv_question.text = shortMessage
tv_longtext.visibility = if (longMessage.isEmpty()) View.GONE else View.VISIBLE
tv_question.visibility = if (shortMessage.isEmpty()) View.GONE else View.VISIBLE
btn_cancel.setSafeOnClickListener {
dismiss()
listener?.onCancel()
}
btn_ok.setSafeOnClickListener {
dismiss()
listener?.onConfirm()
}
}
override fun onStart() {
super.onStart()
val params = dialog?.window?.attributes
params?.width = WindowManager.LayoutParams.MATCH_PARENT
params?.height = WindowManager.LayoutParams.MATCH_PARENT
dialog?.window?.attributes = params as WindowManager.LayoutParams
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
}
open class Listener {
fun onCancel() {
}
open fun onConfirm() {
}
}
companion object {
fun show(
fm: FragmentManager,
longMessage: String = "",
shortMessage: String = "",
listener: Listener
) {
val fragment = ConfirmationDialog()
fragment.longMessage = longMessage
fragment.shortMessage = shortMessage
fragment.listener = listener
fragment.show(fm, fm::class.simpleName)
}
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout 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:background="#color/colorPrimaryDark"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
app:layout_box="all">
<TextView
android:id="#+id/tv_longtext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:fontFamily="sans-serif-condensed"
android:gravity="center"
android:padding="5sp"
android:textColor="#color/white"
android:textSize="16sp"
tools:text="Ambient screen reduces battery life." />
<TextView
android:id="#+id/tv_question"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed"
android:layout_weight="1"
android:gravity="center"
android:paddingTop="5sp"
android:paddingBottom="15sp"
android:textColor="#color/white"
android:textSize="18sp"
tools:text="Turn on?" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5sp">
<android.support.wearable.view.CircledImageView
android:id="#+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:src="#drawable/ic_cc_clear"
app:circle_color="#AFAFAF"
app:circle_radius="25dp"
app:circle_radius_pressed="20dp" />
<android.support.wearable.view.CircledImageView
android:id="#+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:src="#drawable/ic_cc_checkmark"
app:circle_color="#0EB695"
app:circle_radius="25dp"
app:circle_radius_pressed="20dp" />
</FrameLayout>
</LinearLayout>
</android.support.wearable.view.BoxInsetLayout>
Usage:
ConfirmationDialog.show(
childFragmentManager,
"",
"Turn alarm off?",
object : ConfirmationDialog.Listener() {
override fun onConfirm() {
super.onConfirm()
turnAlarm(false)
}
})