I have nested fragments. I have activity A that has fragment B which has List fragment, when user clicks item from ListFragment I want to open new fragment using onListItemClick method.
But I am getting no view found for id error.
Code looks like this:
private ArrayAdapter arrayAdapter;
private ArrayList warnings;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
warnings = new ArrayList();
for(int i=0;i<10;i++) {
warnings.add(i);
}
arrayAdapter = new ArrayAdapter(inflater.getContext(), android.R.layout.simple_list_item_1, warnings);
setListAdapter(arrayAdapter);
//View view = inflater.inflate(R.layout.activity_other, container, false);
return super.onCreateView(inflater,container,savedInstanceState);
}
#Override
public void onItemClick(AdapterView adapter, View view, int position, long id) {
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
ListItemFragment listItemFragment = new ListItemFragment();
FragmentManager manager = getChildFragmentManager();
android.support.v4.app.FragmentTransaction ft = manager.beginTransaction();
ft.replace(android.R.id.tabcontent, listItemFragment);
ft.attach(listItemFragment).addToBackStack(null).commit();
}
it doesn't seem to like android.R.id.tabcontent.
I have other child fragments working fine.
Please help.
Are you nesting the fragments in xml? You can only add nested fragments programmatically. See the documentation here.
The problem I was having, I was trying to attach fragment when I am already in fragment.
This should be done by detaching current fragment and attaching another one.
Now my app works just fine.
Something like this:
ft.detach(getParentFragment()).replace(android.R.id.tabcontent, fragment);
ft.attach(fragment).addToBackStack(null).commit();
Related
I came to the activity class as for need from an fragment and now I want to go back to my earlier fragment.But The fragment was came from an drawer layout.I can't understand what to do....
here is my code.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_answered, container, false);
GridView answeredGridView = (GridView) view.findViewById(R.id.answeredQuestiongridview);
answeredImageAdapter = new AnsweredImageAdapter(getActivity());
answeredImageAdapter.notifyDataSetChanged();
answeredGridView.invalidateViews();
answeredGridView.setAdapter(answeredImageAdapter);
answeredImageAdapter.notifyDataSetChanged();
answeredGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getActivity()," "+position,Toast.LENGTH_SHORT).show();
questionposition = position;
Intent intent = new Intent(getActivity(), AnswerDetailsActivity.class);
intent.putExtra("Image_position",position);
intent.putExtra("question_id",id);
startActivity(intent);
getActivity().finish();
}
});
return view;
}
Suppose now I am in this activity page. and want to go back to my fragment page..I wrote following code and facing the app is unfortunately stopped.
private void answerFragment() {
answeredFragment = new AnsweredFragment();
fragmentManager = getSupportFragmentManager();
//answeredFragment = fragmentManager.findFragmentById("myFragment");
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.main_fragment_container,answeredFragment);
fragmentTransaction.commit();
}
First of all the approach you are following is wrong. Fragments are tied to specific activities. From your code, it seems that in your XYZActivity, you have the AnsweredFragment. On click of an answer you are going to AnswerDetailsActivity. If you are doing it in the same way, then just remove getActivity().finish(); call from here -
answeredGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getActivity()," "+position,Toast.LENGTH_SHORT).show();
questionposition = position;
Intent intent = new Intent(getActivity(), AnswerDetailsActivity.class);
intent.putExtra("Image_position",position);
intent.putExtra("question_id",id);
startActivity(intent);
getActivity().finish();
}
});
In that case, on your Back(Hardware/Software) press you will be able to load your earlier fragment. :)
The context is:
I have an activity consisting of a fragment where there is a form to enter a date and a flight number. There are no other fragments there.
On click of a button, a request is made to a webservice.
A List of Flight Objects is returned from the webservice.
A custom ArrayAdapter is created for each row in the listFragment.
Show the results in a ListFragment in the same Activity on the frontend.
FlightResultAdapter.java:
public class FlightResultAdapter extends ArrayAdapter<Flight>{
public FlightResultAdapter(Context context, List<Flight> flights) {
super(context, R.layout.item_flight, flights);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Flight flight = getItem(position);
if (convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_flight, parent, false);
}
//Set the content of the custom row layout
TextView tvFlightNum = (TextView) convertView.findViewById(R.id.tvFlightNum);
tvFlightNum.setText(flight.getNumber());
return convertView;
}
}
Note: ListFragment has a default layout that consists of a single list view. Source
So I do not need a layout file for the list.
MyActivity.java: A list of objects (flightList.getFlight) is used to create the CustomListAdapter. This code is inside a function that is triggered on an OnClick.
FlightResultAdapter adapter =
new FlightResultAdapter(getApplicationContext(), flightList.getFlight());
FlightFragment.java
public class FlightFragment extends ListFragment {
private List<Flight> flight_items;
public FlightFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
flight_items = new ArrayList<Flight>();
//Initialise the list adapter and set
FlightResultAdapter adapter = new FlightResultAdapter(getActivity(), flight_items);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Flight flight = flight_items.get(position);
Toast.makeText(getActivity(), flight.getNumber(), Toast.LENGTH_LONG).show();
}
}
So what I'm not getting is how to Show the FlightFragment on MyActivity.
Furthermore how to connect it so results are displayed: I think setListAdapter is used?
Update: Connecting the Fragment to the Activity
1. Add a FrameLayout to the activity layout, or other fragment layout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2. Use the FragmentManager to call the Fragment programmatically:
//Create the adapter here
FlightResultAdapter adapter = new FlightResultAdapter(getApplicationContext(), flightList.getFlight());
//Get the Fragment here and set the ListAdapter
FlightFragment ff = new FlightFragment();
// In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
ff.setArguments(getIntent().getExtras());
ff.setListAdapter(adapter);
if (findViewById(R.id.fragment_container) != null) {
//Send the Data to the fragment - Need Help Here
Bundle bundle = new Bundle();
//Show the Fragment
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container, ff);
fragmentTransaction.commit();
}
So the Fragment's OnCreate Method is being called, but the list is empty because I am not passing the Flight Object to the Fragment. How can I do this?
How can I pass the List object to the Fragment?
Because List contains Flight custom class object. so it's not possible to pass it directly.
To pass List<Flight> object:
1. Implement Serializable in Flight class.
2. Use Bundle.putSerializable for sending object from Activity to FlightFragment :
Bundle bundle = getIntent().getExtras();
bundle.putSerializable("flightList", flightList.getFlight());
ff.setArguments(bundle);
...
3. In FlightFragment class override onCreateView method and getArguments method:
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
Bundle args = getArguments();
List<Flight> flightList=(List<Flight>)args.getSerializable("flightList");
....
return super.onCreateView(inflater, container, savedInstanceState);
}
I'm developing an app that uses fragment. In one of these fragments I retrieve data from a remote server and populate a listview. But I noticed that if a user inserts a new value and then goes back to the fragment it doesn't show it. The fragment shows the new value only after the user closes and reopens the app... How can I solve it? I need a way to refresh the fragment every time the user swipes and views it...
This is the code:
public class Page2Fragment extends Fragment {
TestImmagineAdapter adp2;
Archivio archivio;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// fragment not when container null
if (container == null) {
return null;
}
// inflate view from layout
View view = (LinearLayout)inflater.inflate(R.layout.page2,container,false);
ListView mylist = (ListView) view.findViewById(R.id.listView);
archivio = new Archivio();
adp2 = new TestImmagineAdapter(archivio.retTitle(), archivio.retArt(), this.getActivity().getApplicationContext());
mylist.setAdapter(adp2);
/*mylist.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent service = new Intent(view.getContext(), Web.class);
service.putExtra("href", archivio.getLink(position));
startActivity(service);
// TODO Auto-generated method stub
}
});*/
return view;
}
}
You need to notify your adapter of the change.
On the update of your data you use:
adp2.notifyDataSetChanged();
What I want to do is to call one fragment from another on click on item of listview. Program builds without errors however it crash on click on item. Btw I’m making here local Fragment_3 object, I have got already done it in my mainactivity, how to pass it to this function?
Fragment_1.java content:
public class Fragment_1 extends SherlockFragment implements OnItemClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
View view = inflater.inflate(R.layout.fragment_1, container, false);
ListView listView = (ListView) view.findViewById(R.id.listView1);
listView.setOnItemClickListener(this);
return view;
}
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// TODO Auto-generated method stub
Fragment Fragment3 = new Fragment_3();
Integer fragmentId = (Integer) v.getTag();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(fragmentId, Fragment3);
fragmentTransaction.commit();
}
}
My suspicion is that v.getTag() is null; So Integer fragmentId = (Integer) v.getTag(); will end up in fragmentId being null. When unboxing that to an int you'll get a NullPointerException. Why don't you replace fragmentId in fragmentTransaction.replace(fragmentId, Fragment3); with the id of the container that holds current instance of Fragment_1?
I want to replace a fragment containing a list of items with a new fragment depending on the item clicked. This is my code, how do I need to approach this? Should I declare my ListView, Adapter and such in onCreateView or onActivityCreated? The container is a ViewPager if that makes a difference.
public class PreferenceListFragment extends SherlockFragment
{
ListView lv;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return (LinearLayout)inflater.inflate(R.layout.settings, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
lv = (ListView)getView().findViewById(R.id.SettingsLV);
lv.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Preferences.TITLES));
lv.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Log.i("FragmentList", "Item clicked: " + arg2);
// Switch case that starts fragment depending on 'position'.
Fragment1 f1 = new Fragment1();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.pager, f1);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
}
);
}
}
Link to some very weird behaviour from my app.
The setting of adapter and listview should be done in onActivityCreated. OnCreateView is just to draw the user interface for the first time. The processing should be in onActivityCreated(). Refer http://developer.android.com/guide/topics/fundamentals/fragments.html