this keyword in Fragment is not getting implemented while - java

I have created two Fragments and the destination Fragment has a an Expandable List View for which there is an Adapter class as well. And when I'm trying to pass this keyword for context which is one of three parameters, it is not working. Can anyone please guide me where I went wrong.
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//Initializations
expandableListView=view.findViewById(R.id.expand_list);
content_collection();
//listadapter
listAdapter=new ExListAdapter(this, branches,branchntopic);
expandableListView.setAdapter(listAdapter);
}

this is not a valid context in Fragments, you need to use requireContext() or getContext() instead.
Fragment class does not extends from Context class, so Fragment is not a context. But Activity/AppCompatActivity extends from Context class.

You can go for getActivity() or getContext() instead of using this.
Since you are using fragment you cannot pass this keyword as Context.

Use getActivity() in the place of this.
That should solve the problem because the list is not in th fragment context but the activity that calls the fragment

Related

Android drawing app intended for a single View needs to work in multi-view Bottom Navigation Activity app

I'm a completely new Android dev and am rather lost at the moment. I'm following this tutorial as I try to enable drawing to a view in my app which is a "Bottom Navigation Activity" project that features three tabs--or fragments. See screenshot below:
The problem is that the tutorial is intended for an app with a single View and a single standard MainActivity. In this case, the following code is used in the onCreate()method in the project's MainActivity.java class:
public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState):
PaintView paintView = new PaintView(content: this):
setContentView(paintView);
}
}
When I build a single view app, the code works great. No issues. But things can't work in my "Bottom Navigation Activity" project, because the fragments use a ViewModel type that doesn't offer the much needed methods of the View class. My app features 3 fragments, the first of which is named HomeFragment. It is on this fragment that I want all my drawing to take place. The default onCreateView() method for this fragment looks like so:
public class HomeFragment extends Fragment {
private HomeView Model homeViewModel;
public View onCreateView(#NonNull LayoutInflator inflater, ViewGroup container, Bundle savedInstanceState) {
homeViewModel = ViewModelProviders.of(fragment: this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, attachToRoot: false);
return root;
}
}
See screenshot below to see what I've tried to do. You will see that I've added a View class to my project called PaintView (just as created in the tutorial), which contains all the drawing code.
Unfortunately it generates the following compilation error:
Inferred type com.example.mobile_testapp_android_2_ui.home.PaintView for type parameter T is not within its bound; should extend androidx.lifecycle.ViewModel
Any tips on how I can implement the tutorial's PaintView class so that I can use its methods to draw on the "HomeFragment" would be deeply appreciated.
Thank you and very cordially,
Wulf
What you are doing is trying to create a HomeViewModel object with the PaintView class which is not possible. If you want to set PaintView as the view of your HomeFragment, you need to return an object of it as :
//you can return any kind of view object as you like
public View onCreateView(#NonNull LayoutInflator inflater, ViewGroup container, Bundle savedInstanceState) {
PaintView homeFragmentView = new PaintView(requireContext());
// PaintView class must extends View class
return homeFragmentView;
}
I hope, this helps.
Learn more about Fragment here
Learn more about ViewModel here

How the setcontentview is called?

I was tweaking the sample hello world app that android studio provides and found out that I cannot call the setContentView(R.layout.activity_main); outside any method.For example:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
setContentView(R.layout.activity_main); //compilation error
}
I know that I should not be calling setContentView outside onCreate(),but just for a reference I tried it out.I can figure out that this has something to do with Java and not android,but I can't seem to figure out the where the problem exactly lies.Any help will be appreciated.
As per activity life cycle onCreate() is the method called when the activity is first created
OnCreate() is the point where most initialization should go: calling setContentView(int) to inflate the activity's UI, using findViewById to programmatically interact with widgets in the UI, calling managedQuery(android.net.Uri , String[], String, String[], String) to

IllegalStateException while casting context

I am trying to cast an activity to a FragmentActivty object so I could get FragmentManager object
public class Main extends ListActivity {
...
public void showTimePickerDialog(View v) {
FragmentActivity myContext=(FragmentActivity) getApplicationContext(); //Here: java.lang.IllegalStateException: Could not execute method of the activity
FragmentManager fragManager = myContext.getFragmentManager();
DialogFragment newFragment = new uSharedUtility.TimePickerFragment();
newFragment.show(fragManager, "timePicker");
}
}
But when doing it I get:
java.lang.IllegalStateException: Could not execute method of the activity
I cant use getFragmentManager directly because my activity extends from ListActivity which is very necessary.
Please suggest me to get around this error, i really need to use both ListAdapter & Date/Time pickers in the same activity.
I cant use getFragmentManager directly because my activity extends from ListActivity which is very necessary.
It isn't necessary. You can have a ListView in any activity.
Since you're already using fragments, consider using a ListFragment with a FragmentActivity.
You can't cast Application Context to Activity, you must need Activity Context.
(FragmentActivity) getApplicationContext() // Not Possible
getContext(): Returns the context the view is currently running in. Usually the currently active Activity.
getApplicationContext(): Returns the context for the entire application (the process all the Activities are running inside of). Use this instead of the current Activity context if you need a context tied to the lifecycle of the entire application, not just the current Activity.

How to design an Auto-Nested Fragment Class

I'm trying to do something like this:
public class MyFancyFragment<T> extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
getChildFragmentManager().beginTransaction()
.add(R.id.fancy_fragment_layout_id, new T(), "whatever")
.commit();
...
}
...
}
And later specify to the MyFancyFragment class which inner Fragment it's supposed to be using via, e.g.
...new MyFancyFragment<FancyInnerFragmentType>()...
But of course Java won't let me create a new T because that's not how generics work.
There's a reason I'm trying to do it that way. If you do it the way you'd normally be tempted, i.e.:
public class MyFancyFragment<T> extends Fragment {
...
Fragment toShow;
public void setFragment(Fragment toShow) {
this.toShow = toShow;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
getChildFragmentManager().beginTransaction()
.add(R.id.fancy_fragment_layout_id, toShow, "whatever")
.commit();
...
}
...
}
You'll be fine at first, but the issue comes down to the Android Fragment architecture. If you use MyFancyFragment on a fragment backstack, android could at any time destroy the Fragment, and then go to recreate it later via its public empty constructor. When it does this, it's not going to know to call setFragment() for you. I could go the ViewPager design route and set an Adapter to generate the Fragment on demand; but I'm now actually really confused about ViewPager - if the ViewPager fragment is destroyed and recreated via backstack operations, won't it forget about its Adapter?
I also thought maybe I could take a Fragment type when I create MyFancyFragment the first time (so pass a Class instead of a Fragment to setFragment() above), create an instance using it on the fly in onCreateView(), and try to marshal that class type to my bundle in onSaveInstanceState() for later if I need to onCreateView() again: but I don't know how to store non-primitive types like that in the Bundle? I could setup a primitive<->type instance map, but then I lose compiler support to ensure somebody updates that map when they go to create a new instance; and you're screwed if that new instance you wanted to use would have been an anonymous class.
It seems like the only way to go about doing this is to declare MyFancyFragment abstract and create anonymous inner classes extending it that return the target inner fragment (similar to many common examples involving DialogFragment and its onCreateView()); but this gets really hairy if the level of nesting gets very deep :(. In my present situation I have a DialogFragment that contains an A that contains a B that contains a MyFancyFragment, and if I start requiring dynamic subclassing, I'd have to subclass each of DialogFragment, A, B, and MyFrancyFragment to make it work, for each popup I want to show (and there are several). With generics I thought I could just declare an A() and be ok, and T would trickle down; but I can't figure out how to do it or anything like it.
How are we supposed to do this?

Using global onCLickListener

Is it possible to make an onClickListener app-global?
I basically have several fragments that will use the same numpad buttons for input and instead of registering and filtering click events for each button in each fragment I wanted to ask if it was possible to share an onClickListener throughout the entire app.
This is the setting:
public class LoginFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle states) {
this.context = getActivity();
// TODO: Register onClickListener...somehow
context.registerReceiver(receiver, filter); //For the intent listening
view = inflater.inflate(R.layout.layout_login_screen, container, false);
buildUI(null);
return view;
}
(and two different fragments simmilar to this one)
and then the idea was:
public class NumPadListener implements OnClickListener {
#Override
public void onClick(View v) {
System.out.println("Yup...I'm listening?");
// TODO: Do funny intent stuff here
}
}
Is this even possible? And if yes, how? :) If it isn't, do you have any recommendations on how to implement this in the best way? Thanks
Yes, as dymmeh has shown. But the proper way is probably to create your own view component containing all the numpad buttons. You would need to define a layout file, and create a class which would extend some kind of ViewGroup (see compound controls).
This custom component would take care of onClick events of buttons inside it. You could then expose some kind of interface (listener) for activities and fragments to attach to if you need them to react for higher-level events.
Then, you would just include your custom component in any layouts you need instead of copypasting a bunch of buttons and the onClick listener-attaching code.

Categories