I have created an extension of DialogFragment here:
class AlertDialogFragment(context: Context) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = AlertDialog.Builder(activity).apply {
setStyle(STYLE_NO_FRAME, R.style.AlertDialogTheme)
setNeutralButton("Cancel", object : DialogInterface.OnClickListener{
override fun onClick(dialog: DialogInterface?, which: Int) {
}
})
setPositiveButton("Replace", object : DialogInterface.OnClickListener{
override fun onClick(dialog: DialogInterface?, which: Int) {
}
})
setNegativeButton("Delete", object : DialogInterface.OnClickListener{
override fun onClick(dialog: DialogInterface?, which: Int) {
}
})
}
return dialog.create()
}
}
As you can see above I have applied my AlertDialogTheme to the dialog:
<style name="AlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:background">#color/colorPrimary</item>
<item name="android:windowBackground">#color/colorPrimary</item>
</style>
However when my dialog is shown:
override fun onClick(v: View) {
if (v is AppCompatImageButton){
val dialog = AlertDialogFragment(this)
dialog.show(supportFragmentManager, "alertDialog")
}
}
The background of the dialog is black (~#333 I think). My #color/colorPrimary is white so that is what the background is meant to be.
Any idea what the problem is?
you can do it like that
class AlertDialogFragment : DialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container:ViewGroup?,savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
var view = inflater.inflate(R.layout.fragment_dialog, container, false)
view.delete.setOnClickListener { }
view.cancel.setOnClickListener { }
view.replace.setOnClickListener { }
return view
}
}
create xml layout fragment_dialog and design it as you want :
<?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="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<Button
android:id="#+id/cancel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="cancel"
android:layout_weight="1"/>
<Button
android:id="#+id/replace"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="replace"
android:layout_weight="1"/>
<Button
android:id="#+id/delete"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="delete"
android:layout_weight="1"/>
</LinearLayout>
and finally show your dialog with your custom style just like that :
val dialog = AlertDialogFragment()
dialog.setStyle(DialogFragment.STYLE_NO_FRAME , R.style.AlertDialogTheme)
dialog.show(supportFragmentManager, "alertDialog")
Related
Hi I have an simple app with Bottom Navigation Activity. In Home Fragment I have a Button called Fruits. It opens a PopupWindow. In the popup is a RecyclerView with 4 Buttons(fruits names).
I want, when I press on a Button in the PopupWindow, to change the name of Button(called Fruits) form home_fragment, in whatever fruit was chosen.
HomeFragment:
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
return root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.Fruits.setOnClickListener {
show_popup(requireContext(), view, R.layout.fruits_popup)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
fun show_popup(c: Context, v: View, l: Int){
val popup_window = PopupWindow(c)
val inflater = layoutInflater.inflate(l, null)
val recyclerView: RecyclerView = inflater.findViewById(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = FruitsAdapter()
popup_window.contentView = inflater
popup_window.isFocusable = true
popup_window.isOutsideTouchable = true
popup_window.showAtLocation(v, Gravity.CENTER, 0, 0)
}
}
FruitsAdapter:
class FruitsAdapter : RecyclerView.Adapter<FruitsAdapter.FruitsViewHolder>() {
private val list = listOf<String>("Banana", "Orange", "Apple", "Watermelon")
class FruitsViewHolder(val view: View): RecyclerView.ViewHolder(view) {
val button = view.findViewById<Button>(R.id.fruit)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitsViewHolder {
val layout = LayoutInflater.from(parent.context).inflate(R.layout.fruit, parent, false)
return FruitsViewHolder(layout)
}
override fun onBindViewHolder(holder: FruitsViewHolder, position: Int) {
val item = list.get(position)
holder.button.text = item.toString()
}
override fun getItemCount(): Int {
return list.size
}
}
fragment_gome.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"
tools:context=".ui.home.HomeFragment">
<Button
android:id="#+id/Fruits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fruits"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.254" />
</androidx.constraintlayout.widget.ConstraintLayout>
fruits_popup.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_view"/>
</FrameLayout>
fruit.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fruit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:padding="8dp" />
Try to google with keyword 'callback' bro
I want to move a ConstraintLayout programmatically. I looked through some solutions on stack overflow but they didn't work for me.
There are two ConstraintLayouts placed vertically. When the code goes into else if("android.permission.CAMERA" in permissionList.toString(), the above constraint layout (layoutLocation) will be invisible and the below constraint layout (layoutCamera) will come up and take its position. I mark where I should use declare it with 'want to use here'.
Code (apology to not ba able to post the whole code due to patent reason)
class SplashFragment : Fragment() {
private lateinit var mContext: MainActivity
private lateinit var binding : FragmentSplashBinding
private val viewModel : SplashViewModel by inject()
private val getPermissionUseCase : GetPermissionUseCase by inject()
override fun onAttach(context: Context) {
super.onAttach(context)
mContext = context as MainActivity
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_splash, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.viewModel = viewModel
binding.lifecycleOwner = viewLifecycleOwner
}
private fun actionApplicationSetting(permissionList : List<String>) {
val layoutInflater = LayoutInflater.from(context)
val view = layoutInflater.inflate(R.layout.dialog_splash, null)
val alertDialog = AlertDialog.Builder(requireContext(), R.style.CustomAlertDialog).setView(view).create()
val layoutLocation : ConstraintLayout = view.findViewById(R.id.layout_box_location)
val layoutCamera : ConstraintLayout = view.findViewById(R.id.layout_box_camera)
for(permission in permissionList) {
if("android.permission.CAMERA" in permissionList.toString() && "android.permission.ACCESS_COARSE_LOCATION" in permissionList.toString()) {
layoutLocation.background = AppCompatResources.getDrawable(mContext, R.drawable.auth_level_blue)
layoutCamera.background = AppCompatResources.getDrawable(mContext, R.drawable.auth_level_blue)
}else if("android.permission.ACCESS_COARSE_LOCATION" in permissionList.toString()) {
layoutLocation.background = AppCompatResources.getDrawable(mContext, R.drawable.auth_level_blue)
}else if("android.permission.CAMERA" in permissionList.toString()) {
layoutLocation.visibility = View.INVISIBLE
// want to use here
}
}
alertDialog.show()
}
}
XML
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layout_main"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginStart="70dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="#+id/layout_wrapper"
app:layout_constraintEnd_toEndOf="#+id/layout_wrapper"
app:layout_constraintStart_toStartOf="#+id/layout_wrapper">
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layout_wrapper"
android:layout_width="match_parent"
android:layout_height="180dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layout_box_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layout_box_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/layout_box_location" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Instead of layoutLocation.visibility = View.INVISIBLE try layoutLocation.visibility = View.GONE
In one of my app, I am using Android Navigation Architecture component. Everything was going fine and smooth. But when I wanted to navigate to DialogFrgment, I got stuck. Though DialogFragment triggered, but no layout is seen. Just visible the overlap blur background. Can't figure out the actual problem. Here is the code I use to display dialogFragment.
This is custom layout I wanted to show
terms_and_condition.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:ignore="WebViewLayout">
<LinearLayout
android:id="#+id/linearLayout6"
android:layout_width="match_parent"
android:layout_height="#dimen/_60sdp"
android:background="#color/colorAccent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_20sdp"
android:layout_weight="3"
android:text="#string/terms_amp_conditions"
android:textSize="#dimen/_15ssp"
android:textStyle="bold"
android:textColor="#color/white" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/close_privacy_policy_dialog_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="#drawable/ic_close" />
</LinearLayout>
<WebView
android:id="#+id/privacy_policy_web_view"
android:layout_width="match_parent"
android:layout_height="#dimen/_300sdp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/linearLayout6"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the base class for Dialog fragment
BaseDialogFragment.kt
abstract class BaseDialogFragment : DaggerAppCompatDialogFragment() {
#LayoutRes
abstract fun getLayoutResource(): Int
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return container?.inflate(getLayoutResource())
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window?.let {
it.requestFeature(FEATURE_NO_TITLE)
it.setBackgroundDrawableResource(R.color.transparent)
}
return dialog
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialog?.window?.setLayout(
MATCH_PARENT,
WRAP_CONTENT
)
}
protected fun disableDismissOnBackPress() {
dialog?.setOnKeyListener { _, keyCode, event ->
if (keyCode == KEYCODE_BACK) {
if (event.action != ACTION_DOWN) true else true
} else {
false
}
}
}
}
TermsAndConditionDialogFragment.kt
class TermsAndConditionDialogFragment: BaseDialogFragment() {
override fun getLayoutResource() = R.layout.dialog_terms_and_condition
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val closeTheDialogImageView = view.findViewById<ImageView>(R.id.close_privacy_policy_dialog_image_view)
val privacyPolicyWebView = view.findViewById<WebView>(R.id.privacy_policy_web_view)
privacyPolicyWebView.loadUrl("file:///android_asset/privacy_policy.html")
closeTheDialogImageView.setOnClickListener { dialog?.dismiss() }
}
}
navigation_graph.xml
<navigation
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/navigation_graph"
app:startDestination="#id/splashFragment">
<dialog
android:id="#+id/termsAndConditionDialogFragment"
android:name="com.aomi.mybase.ui.feature.termAndCondition.TermsAndConditionDialogFragment"
tools:layout="#layout/dialog_terms_and_condition"/>
</navigation>
SignUpFragment.kt
terms_and_condition_button.setOnClickListener {
findNavController().navigate(R.id.termsAndConditionDialogFragment)
}
Change your onCreateDialog like below and replace your DaggerAppCompatDialogFragment to DialogFragment
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return this.activity?.let {
val builder = AlertDialog.Builder(it)
val inflater = requireActivity().layoutInflater
val layoutId: Int = R.layout.your_layout
val rootView = inflater.inflate(layoutId, null)
builder.setView(rootView)
val alertDialog = builder.create()
alertDialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
alertDialog
} ?: throw IllegalStateException("Activity cannot be null")
}
You can also use DaggerAppCompatDialogFragment when use Dagger2 as Dependency Injection. Here is the code
class TermsAndConditionDialogFragment: DaggerAppCompatDialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val rootView = requireActivity().layoutInflater.inflate(R.layout.dialog_terms_and_condition, null)
initWidget(rootView)
return this.activity?.let {
val dialog = AlertDialog.Builder(it).setView(rootView).create()
dialog.window?.let { window ->
window.setLayout(MATCH_PARENT, WRAP_CONTENT)
window.requestFeature(FEATURE_NO_TITLE)
window.setBackgroundDrawableResource(R.color.transparent)
}
dialog
} ?: throw IllegalStateException("Activity cannot be null")
}
private fun initWidget(view: View) {
val closeTheDialogImageView = view.findViewById<ImageView>(R.id.close_privacy_policy_dialog_image_view)
val privacyPolicyWebView = view.findViewById<WebView>(R.id.privacy_policy_web_view)
privacyPolicyWebView.loadUrl("file:///android_asset/terms_and_condition.html")
closeTheDialogImageView.setOnClickListener { dialog?.dismiss() }
}
}
I want to achieve a layout as shown in the Android Studio preview (left). However if executed in the emulator, only the button is visible and the RecyclerView is not visible/populated (right).
The XML code:
<?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"
style="#style/AppTheme">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:name="com.example.app.ItemFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".ItemFragment"
tools:listitem="#layout/fragment_item"
android:scrollbars="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_margin="#dimen/fab_margin"
android:clickable="true"
android:focusable="true"
android:src="#android:drawable/ic_input_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
However if the RecyclerView is alone in the fragment the list is populated (but of course the action button is not showing). Code see below. And yes, my list which should be shown is not empty.
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView 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/list"
android:name="com.example.app.ItemFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".ItemFragment"
tools:listitem="#layout/fragment_item" >
</androidx.recyclerview.widget.RecyclerView>
I have already tried using RelativeLayout and FrameLayout, but I still get the same result. The same behavior occurs if I use e.g. a TextView instead of the action button.
--- Requested additional info ---
Adapter class (automatically generated by Android Studio, template):
class MyItemRecyclerViewAdapter(
private val mValues: List<DummyItem>,
private val mListener: OnListFragmentInteractionListener?
) : RecyclerView.Adapter<MyItemRecyclerViewAdapter.ViewHolder>() {
private val mOnClickListener: View.OnClickListener
init {
mOnClickListener = View.OnClickListener { v ->
val item = v.tag as DummyItem
// Notify the active callbacks interface (the activity, if the fragment is attached to
// one) that an item has been selected.
mListener?.onListFragmentInteraction(item)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.fragment_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = mValues[position]
holder.mIdView.text = item.id
holder.mContentView.text = item.content
with(holder.mView) {
tag = item
setOnClickListener(mOnClickListener)
}
}
override fun getItemCount(): Int = mValues.size
inner class ViewHolder(val mView: View) : RecyclerView.ViewHolder(mView) {
val mIdView: TextView = mView.item_number
val mContentView: TextView = mView.content
override fun toString(): String {
return super.toString() + " '" + mContentView.text + "'"
}
}
}
List fragment (automatically generated by Android Studio, template):
class ItemFragment : Fragment() {
// TODO: Customize parameters
private var columnCount = 1
private var listener: OnListFragmentInteractionListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
columnCount = it.getInt(ARG_COLUMN_COUNT)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_item_list, container, false)
// Set the adapter
if (view is RecyclerView) {
with(view) {
layoutManager = when {
columnCount <= 1 -> LinearLayoutManager(context)
else -> GridLayoutManager(context, columnCount)
}
adapter = MyItemRecyclerViewAdapter(DummyContent.ITEMS, listener)
}
}
return view
}
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnListFragmentInteractionListener) {
listener = context
} else {
throw RuntimeException(context.toString() + " must implement OnListFragmentInteractionListener")
}
}
override fun onDetach() {
super.onDetach()
listener = null
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
*
*
* See the Android Training lesson
* [Communicating with Other Fragments](http://developer.android.com/training/basics/fragments/communicating.html)
* for more information.
*/
interface OnListFragmentInteractionListener {
// TODO: Update argument type and name
fun onListFragmentInteraction(item: DummyItem?)
}
companion object {
// TODO: Customize parameter argument names
const val ARG_COLUMN_COUNT = "column-count"
// TODO: Customize parameter initialization
#JvmStatic
fun newInstance(columnCount: Int) =
ItemFragment().apply {
arguments = Bundle().apply {
putInt(ARG_COLUMN_COUNT, columnCount)
}
}
}
}
Try this for your layout
<?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"
style="#style/AppTheme"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:name="com.example.app.ItemFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layoutManager="LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:context=".ItemFragment"
tools:listitem="#layout/fragment_item" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_margin="#dimen/fab_margin"
android:clickable="true"
android:focusable="true"
android:src="#android:drawable/ic_input_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Inside ItemFragment.kt replace onCreateView with
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_item_list, container, false)
}
After that go ahead and implement onViewCreated as such
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
with(list) {
layoutManager = when {
columnCount <= 1 -> LinearLayoutManager(requireContext())
else -> GridLayoutManager(requireContext(), columnCount)
}
adapter = MyItemRecyclerViewAdapter(DummyContent.ITEMS)
}
}
This should fix your problem because the AS template is assuming that the rootview will be a RecyclerView and is treating the whole layout as such.
Getting this Error
kotlin.NotImplementedError: An operation is not implemented: not implemented
I am implementing an ImageButton click listener
Requirement :- I want to perform an action on imagebutton click , but getting the above mentioned error
Correct me and also if there is any other work around to implement imagebutton click listener, do provide it , Thanks
Here is the fragment java class
class FragmentClass : Fragment(), View.OnClickListener {
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
when (v?.id) {
R.id.back_icon -> {
Toast.makeText(activity, "back button pressed", Toast.LENGTH_SHORT).show()
activity.onBackPressed()
}
else -> {
}
}
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view: View = inflater!!.inflate(R.layout.fragment_class, container,
false)
val activity = getActivity()
var input_name = view.findViewById(R.id.input_name) as EditText
var tv_addbucket = view.findViewById(R.id.tv_addbucket) as TextView
val back_icon: ImageButton = view.findViewById(R.id.back_icon)
back_icon.setOnClickListener(this)
tv_addbucket.setOnClickListener(View.OnClickListener {
Toast.makeText(activity, input_name.text, Toast.LENGTH_SHORT).show()
})
return view;
}
}
and then the fragment_class. xml
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"
android:padding="10dp">
<ImageButton
android:id="#+id/back_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#0000"
android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"
android:src="#drawable/back_icon" />
<TextView
android:id="#+id/tv_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Add Bucket" />
</RelativeLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header"
android:fillViewport="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="60dp">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_name"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/input_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Bucket Name"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<TextView
android:id="#+id/tv_addbucket"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:background="#drawable/blue_stroke_background"
android:gravity="center"
android:padding="15dp"
android:text="Add"
android:textColor="#color/white" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
Just remove TODO( ... ) from your onClickListener:
override fun onClick(v: View?) {
// No TODO here
when (v?.id) {
...
}
}
TODO(...) is Kotlin function which always throws NotImplementedError. If you want to mark something with TODO but to not throw exception - just use TODO with comments:
override fun onClick(v: View?) {
//TODO: implement later
when (v?.id) {
...
}
}
TODO() is an inline function in Kotlin. It ALWAYS will throw NotImplementedError. See #documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-t-o-d-o.html
If you want just to mark that this fragment of code still needs work, use // TODO. Then, the mark will be visible in TODO section, but will not throw exception.
I implemented this
val extraTime = arrayListOf<String>("1 hour")
val extraTimeAdapter = CustomSpinDeliveryExtraTimeAdapter(context!!, R.layout
.simple_spinner_text_middle_down_arrow, extraTime)
spinCustomTime.adapter = extraTimeAdapter
spinCustomTime.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
After removing todo from this below code
spinCustomTime.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
}
}
solved my problem.
Also see this doc link for clarification
See #documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-t-o-d-o.html
Just remove TODO("not implemented") from your onClickListener: