I've got the following function:
public static class ListFragment extends Fragment {
private ParseQueryAdapter<ParseObject> mainAdapter;
private ListView listView;
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState )
{
View rootView = inflater.inflate(R.layout.fragment_list, container, false );
mainAdapter = new ParseQueryAdapter<ParseObject>( this, "Todo" );
mainAdapter.setTextKey("title");
mainAdapter.setImageKey("image");
// Initialize ListView and set initial view to mainAdapter
listView = (ListView) findViewById(R.id.list);
listView.setAdapter(mainAdapter);
mainAdapter.loadObjects();
return rootView;
}
}
The errors returned are:
The constructor ParseQueryAdapter(MainActivity.ListFragment, String) is undefined MainActivity.java
Cannot make a static reference to the non-static method findViewById(int) from the type Activity MainActivity.java
I can assume that the first one due to the change of the object of type this but I would like a more seasoned input on the correct fix.
The second error though thoroughly confounds as it appears to be valid to my eyes.
Appreciate any input.
1) Change the instantiation of ParseQueryAdapter as follows. The code is in a Fragment, but ParseQueryAdapter requires a Context object.
mainAdapter = new ParseQueryAdapter<ParseObject>( this.getActivity(), "Todo" );
2) Remove the static modifier from your class definition.
Related
I'm trying to follow this tutorial
I have a project that uses the Sidebar Navigation, so I have one MainActivity and multiple Fragments. At ~6:20 into the video, you can see the following code:
PersonListAdapter adapter = new PersonListAdapter(
this,
R.layout.adapter_view_layout,
peopleList);
The constructor for the PersonListAdapter Class is:
public PersonListAdapter(Context context, int resource, ArrayList<Attacks> objects) {
super(context, resource, objects);
this.mContext = mContext;
mResource = resource;
}
The problem lies with Context.
If I use the word "this", there is a red line.
If I replace
"this" with "getActivity()", there is no red line, but the app
crashes when I run it.
I've also tried "this.getContext()" and "this.getActivity()"
I have also tried replacing "this" with "getActivity().getApplicationContext()", and the app crashes.
The tutorial uses MainActivity.java, but my code is in FragmentCharacters.java. I don't know what I'm supposed to write in place of "this", or if I need to change something in the PersonListAdapter class for Context.
You cannot use a Fragment as a Context, because Fragment doesn't inherit from Context.
However, if you consult the Fragment lifecycle, you can see that the Fragment has access to its host Activity at any time between the lifecycle callbacks OnActivityCreated() and onDestroyView(). If you try to access the Activity before OnActivityCreated(), for example, it will probably return null.
So make sure you are calling getActivity() from within onActivityCreated() or later, which will make sure your Activity is available.
UPDATE, I Provided a Case Example inside the Code Snippets as well, and I chose "FragmentName" as Fragment name for example.
First Look at This Fragment Structure.
I Added [mAdapter] in Both onCreate and onCreateView
And I Added FragmentName.this for the Forth argument
The Reason is, You can send data from The Adapter to Other Activities with it, for Example FragmentName.mAdapter.getLayoutPosition()
But, Let's assume We have an ImageView which is In MainActivity and we want to use it in our Adapter, So let's Establish an ImageView In our Fragment as well, Notice I Declared the ImageView Inside onCreate
And, For Another Example, Let's Assume we Have a Public Void at the End of our Fragment as Well, It can be Literally Anything. I Named it ExampleClass
/////////FIRST TAKE A LOOK AT FRAGMENT//////////
public class FragmentName extends Fragment {
PersonListAdapter adapter;
ImageView imageView; // For Example thi ImageView is from MainActivity
public FragmentName() {
...
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
adapter = new PersonListAdapter(getContext(), R.layout.adapter_view_layout, peopleList, FragmentName.this);
imageView = (ImageView) getActivity().findViewById(R.id.ImageView);
// This Imageview is in Another Activity, Like MainActivity
// So we Need to Find it Using 'getActivity()'
...
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
adapter = new PersonListAdapter(getContext(), R.layout.adapter_view_layout, peopleList, FragmentName.this);
}
}
public void ExampleClass(int color, ...) {
...
}
////////////////////////////////////////////////////////////////
Now, Let's take this Example into our Adapter as well, to Show how it can be Used.
But, In the Adapter Use [FragmentName], Instead of [Fragment] like Below:
///////////NOW INSIDE YOUR ADAPTER/////////////
public class PersonListAdapter extends RecyclerView.Adapter < PersonListAdapter.myViewHolder > {
FragmentName myFragment; // SEE WHAT HAPPENDED HERE?
...
public PersonListAdapter(Context context, int resource, ArrayList < Attacks > objects, FragmentName fragment) {
super(context, resource, objects);
this.mContext = mContext;
mResource = resource;
this.myFragment = fragment
}
#Override
public PersonListAdapter.myViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Example use of myFragment
// Lets Execute ExmpleClass inside the Fragment
myFragment.ExampleClass(int color, ...);
// Let's Use the ImageView from MainActivity Here
myFragment.imageView.setImageRresource(...);
...
}
...
// YOU CAN NOW USE "myFragment" As a Context In your Adapter
The Good Part about this is That You can Use Fragment As CONTEXT in Your PersonListAdapter
Update: The second Code, onCreateViewHolder is wrong, it has to be inside a ClickListener in ViewHolder or onBindViewHolder
In Android studio, when I create a new Activity with a fragment, it makes a inner static class in my activity.
The problem is that, because it's a static and inner class, I can't do much with it.
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//ArrayList<String> contactList=new ArrayList<String>();
View rootView = inflater.inflate(R.layout.fragment_search, container, false);
//contactList.add("One test);
//ArrayAdapter <String> arrayAdapter= new ArrayAdapter<String> (getActivity(),R.layout.list_item_forecast,
// R.id.list_item_forecast_textview,contactList);
//ListView lv= (ListView)rootView.findViewById(R.id.listview_forecast);
//lv.setAdapter(arrayAdapter);
return rootView;
}
}
The code I commented is what I added, and works.
But I would like to do more: add listener to that ListView items, etc..
If Andoid studio put the placeholderFragment as a static inner class, it means that it's a good and easy way, but I don't know how to continue it.
So, to be more specific, for example, How can a put a listener for the listview items?
Thanks a lot.
The PlaceholderFragment should not be used. It is a placeholder only. If you add your own fragments, you should finally delete the place holder.
You should create a Fragment class of your own (via new->fragment) and add your logic to it. In your activity, implement the methods to be called when an item in your drawer is clicked. Then, implement the logic to activate your fragment.
If you need more information or code examples, please let me know.
Below code shows null pointer exception..
public class MyFragment extends Fragment {
private String[] eArray = getActivity()
.getResources()
.getStringArray(R.array.English);
What are the other options, searching in stackoverflow did not give me success..
I am using FragmentPagerAdapter also.. which is not related to this eArray.. but it contains data for images.
getActivity() is returning null because you are using it before fragment get attached to Activity.
You need to initialize this at onCreateView
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
eArray = getActivity().getResources().getStringArray(R.array.English);
}
I have a dialog which extends DialogFragment:
public class MyCustomDialogFragment extends DialogFragment {
static MyCustomDialogFragment newInstance() {
return new MyCustomDialogFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.institutional_info_custom_list, container, false);
return view;
}
}
And this is where I use this dialog (it is inside an onclick listener):
MyCustomDialogFragment newFragment = MyCustomDialogFragment.newInstance();
View DialogView = newFragment.getView();
DetailListView = (ListView) DialogView.findViewById(R.id.custom_dialog_list);
final MasterDetailArrayAdapter adapter = new MasterDetailArrayAdapter(ComeHaInvestito.this, MasterAndDetailstatisticsInfoList);
DetailListView.setAdapter(adapter);
newFragment.show(getFragmentManager(), "master_detail_dialog");
MasterAndDetailstatitiscsInfoList is a list I am using with my custom ArrayAdapter, but the problem is with the View of the DialogFragment: it is null! Why? I read the android documentation and they say that getView() returns the View of the dialog which is the one returned by the onCreateView() overriden method.
So why I get a null pointer exception when trying to revocer the ListView which is in the dialogFragments layout???
Sorry but this does not make sense to me. An explanation will be appreciated.
Thanks!
Use setArguments() to provide the dataset for the Adapter to the DialogFragmet. In DialogFragment override onViewCreated(), retrieve the ListView, create the Adapter and set it to the ListView
I have a fragment that is a "timer" that I can add anywhere. In the fragment I change a textView programatically, and it runs beautifully. My problem is when it comes to using a view from the layout inflated by the constructor(? Not sure if that's the right terminology) in another method below it.
public class Timer_fragment extends android.support.v4.app.Fragment {
int testpins;
String testedpin;
TextView text;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.timer_frag, container, false);
TextView text = (TextView) v.findViewById(R.id.pwd_status);
text.setText("Setting text in fragment not main");
/* set the TextView's text, click listeners, etc. */
updateStatus();
return v;
}
All of that code works with no errors but when I try to add this method:
private void updateStatus() {
TextView text = (TextView) findViewById(R.id.pwd_status);
testPin();
text.setText(testedpin);
}
I get a red line under findViewById saying The method findViewById(int) is undefined for the type Timer_fragment.
I thought about inflating the view in all of my methods and not returning them, but surely that would affect performance somehow right?
Just tried inflating the layout before using the view but I get an error on the word inflater and container saying that they can't be resolved.
Am I going about this correctly?
You already have a member variable in the scope of your Fragment called text. Don't re-declare it in your methods, just assign it.
text = (TextView) v.findViewById(R.id.pwd_status);
and
private void upateStatus() {
testPin();
text.setText(testedpin);
}
The method 'findViewById' is provided by the activity. While this class extends Fragment, you will not have access to activity related method calls unless you provide the activity to the fragment. Check out: http://developer.android.com/reference/android/app/Activity.html#findViewById(int)
Basically, either pass in the instance of the activity to the Timer_fragment:
private final Activity _activity;
Timer_fragment(Activity activity)
{
_activity = activity;
}
...
private void updateStatus()
{
TextView text = (TextView) _activity.findViewById(R.id.pwd_status);
testPin();
text.setText(testedpin);
}
Or set the text of the view from within whichever activity is being used, and not from within the timer class.
Just replace findViewById with getActivity().findViewById.
findViewById method is defined inside the Activity class. Fragments aren’t activites. But the fragment can get a reference to the Activity that added it to a screen using the method getActivity.