I am calling one button click listener in my java class that will open the Kotlin class fragment. I have written the code but facing a small issue related to a new instance in java class. Please guied on this.
Java Class Code:
notifications.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fp = getSupportFragmentManager();
FragmentTransaction ok = fp.beginTransaction();
ok.add(R.id.fragment_container_dashboard, Weather.newInstance());
ok.addToBackStack(null);
ok.commit();
}
});
*Can not resolve the method 'newInstance' in 'Weather.'
Kotlin Class:
class Weather : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Get the custom view for this fragment layout
return inflater!!.inflate(R.layout.weather, container, false)
}
}
How to resolve this?
Assuming that newInstance() is placed in the companion object of Weather fragment class, from within Java code you can call it like this:
Weather.Companion.newInstance()
Related
I have a view model I have added a click event listener. How do I navigate from that ViewModel into a Fragment
The ViewModel Code
class PromoAdapter(var promo: ArrayList<PromoModal>) :
RecyclerView.Adapter<PromoAdapter.UserViewHolder>() {
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(promo[position])
holder.promoRow.setOnClickListener() {
// Navigate to Fragment with name UserFragment
};
}
}
User Fragment Code
class UserFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view: View = LayoutInflater.from(container!!.context)
.inflate(R.layout.user_page_fragment, container, false)
}
}
I have tried writing the following code still not working
Inside the ViewModel Click Event
val intent = Intent(itemView.context, UserFragment::class.java)
itemView.context?.startActivity(intent)
I cant find something working any help will be appreciated
It's better to move the click listener to a fragment
In Adapter:
class PromoAdapter(
var promo: ArrayList<PromoModal>,
val openFragment: (promoModal: PromoModal) -> Unit
) :
RecyclerView.Adapter<PromoAdapter.UserViewHolder>() {
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(promo[position])
val currentItem = promo.getOrNull(position) ?: return
holder.promoRow.setOnClickListener {
openFragment(currentItem)
};
}
}
In Fragment:
val mAdapter = PromoAdapter(
promo = promoList,
openFragment = { promoModal ->
// Navigate to Fragment with name UserFragment
}
)
I want to send the data from MainActivity to Fragment but i don't want to pass the data in the arguments when i am making the transaction to the fragment like below:
val bundle = Bundle()
bundle.putString("name", name)
val fragment = BlankFragment(this)
fragment.arguments = bundle
supportFragmentManager.beginTransaction().replace(R.id.fragmentView, fragment).commit()
I want to pass the data from the activity to the fragment using the interface. I am able to send the data from the fragment to the activity using the interface but not vice versa.
You have an instance of a fragment in fragment, so provided it has a property name you can just say fragment.name = "name".
Note that when the app is restarted by the system after it is killed, the system will try to restore the fragment by calling it with empty constructor. So you can't have a constructor that have arguments, and also you won't get a name if you set it using fragment.name = "name". Using a bundle ensures that that the fragment gets its arguments after restart.
I hope this can resolve your issue
Adding fragment to Activity
val interfaceCall:FetchDataInterface = DataFragment.newInstance("data")
interfaceCall.getData("data from interface")
supportFragmentManager.beginTransaction()
.replace(R.id.frame, DataFragment.newInstance("data"))
.commit()
Fragment Class
class DataFragment : Fragment(),MainActivity.FetchDataInterface {
// TODO: Rename and change types of parameters
private var param1: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(DATA)
Log.e("checkParam", " : $param1")
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_data, container, false)
}
companion object {
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(value: String) =
DataFragment().apply {
arguments = Bundle().apply {
putString(DATA, value)
}
}
}
override fun getData(value: String) {
Log.e("checkParam", " interface: $value")
}
}
Interface
interface FetchDataInterface{
fun getData(value:String)
}
Tryout this onces
In activity.....
TextEditorDialogFragment textEditorDialogFragment =
TextEditorDialogFragment.show(this, text, colorCode);
In Fragment....
public class TextEditorDialogFragment extends DialogFragment {
public static final String TAG = TextEditorDialogFragment.class.getSimpleName();
String inputText;
int colorCode;
public static TextEditorDialogFragment show(#NonNull AppCompatActivity appCompatActivity, #NonNull String inputText_, #ColorInt int colorCode_) {
inputText =inputText_;
colorCode=colorCode_;
TextEditorDialogFragment fragment = new TextEditorDialogFragment();
fragment.show(appCompatActivity.getSupportFragmentManager(), TAG);
return fragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.add_text_dialog, container, false);
}
}
This question already has answers here:
Starting DialogFragment from a class extending RecyclerView.ViewHolder
(2 answers)
DialogFragment From RecyclerView
(1 answer)
Closed 7 months ago.
I have a DialogFragment that I want to show when clicking on an item inside a Recycler View. Here are my files:
DialogFragment.kt:
class TaskDialogFragment:DialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var rootView: View = inflater.inflate(R.layout.task_dialog, container, false)
return rootView
}
}
RecyclerViewAdapter.kt:
class RecycleViewAdapter(): RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>() {
private lateinit var dao: TaskDao
private lateinit var dialogFragment: TaskDialogFragment
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
init {
itemView.setOnClickListener { v: View ->
// this is where I want my dialogFragment to be opened from
dialogFragment = TaskDialogFragment()
dialogFragment.show(supportFragmentManager, "taskDialog")
}
}
}
I have tried following the steps shown here https://developer.android.com/guide/fragments/dialogs but I get an error saying Unresolved Reference: supportFragmentManager.
How would I open this dialog from the recycler view? Any tips would be appreciated.
I am trying to pass a childFragmentManager from a fragment to an adapter. The current fragment is called from a different fragment and not activity.
the fragment class has a val
class DisplaySchoolFrag : BaseFragment<binding, DisplaySchoolViewModel>{
...
private val adapter = DisplaySchoolAdapter(childFragmentManager)
In the adapter I just have the const declaration for childFrag no other usage for now.
class DisplaySchoolAdapter(childFrag: FragmentManager) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
I need the childFragmentManager inside the adapter, because inside the adapter class theres a button which leads to bottomsheet fragment.
FragmentHostCallback<?> mhost
getChildFrar(){
if (this.mHost == null) {
throw new IllegalStateException("Fragment " + this + " has not been attached yet.");
and this line is causing the Fragment not attached, Unable to instantiate fragment calling fragment const caused exception
i tried this
lateinit var childFrag : FragmentManager
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
childFrag = childFragmentManager
return super.onCreateView(inflater, container, savedInstanceState)
}
and passing the childFrag into the DisplaySchoolAdapter(childFrag) declaration still getting the error.
You should pass in a callback in to DisplaySchoolAdapter and override the individual item's setOnClickListener listener and invoke the callback.
class DisplaySchoolAdapter(lambdaToBeInvoked: () -> Unit): RecyclerView.Adapter<SomeViewHolder>() {
... set up your adapter
override fun onBindViewHolder(holder: SomeViewHolder, position: Int) {
val item = items[position]
holder.bind(item)
holder.itemView.setOnClickListener { lambdaToBeInvoked() }
}
}
You can fill in the implementation details in the rest of your adapter, but the onBindViewHolder is where you would invoke the callback. If you need to pass any parameters into there, then feel free to add those in your implementation.
Then in your fragment when you instantiate your adapter you would pass in what you want your childFragment to do.
class YourFragment: FragmentActivity() {
override onCreate() {
val adapter = DisplaySchoolAdapter {
// have your childFragment navigate to somewhere
}
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager()
}
}
In android latest versions, a new feature of Bottom sheets has been introduced which allows showing popups as bottom sheets. For example,
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
View sheetView = getLayoutInflater().inflate(R.layout.any, null);
bottomSheetDialog.setContentView(sheetView);
bottomSheetDialog.show();
And you can show the popup as bottom sheet view.
My problem is that I have to do a lot of code for my apps functionality say 100-200 lines of code but keeping this code inside same activity or fragment makes my code ugly and unmanageable. Is there a way that I can extract out this code to some Fragment or other activity such that all the code related to bottom sheet dialog remains inside it's own class.
I am not looking up for any java hacks. Rather android way of doing this is expected.
How to open and close the bottomsheet view?
consider to use BottomSheetDialogFragment instead
As Zafer Celaloglu said can do so
kotlin
class MyDialogFragment : BottomSheetDialogFragment() {
companion object {
const val TAG = "FilterDialogFragment"
fun newInstance() = FilterDialogFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_dialog_my_layout, container, false)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
java
public class MyDialogFragment extends BottomSheetDialogFragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_dialog_my_layout, container, false)
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
and call in activity like that
kotlin
MyDialogFragment.newInstance().show(supportFragmentManager,MyDialogFragment.TAG)
java
MyDialogFragment myDialogFragment = new MyDialogFragment();
myDialogFragment.show(getSupportFragmentManager(), "MyDialogFragment");