On my fragment named locate_map I declared a string array and converted it as a String ArrayList. I would like that ArrayList be pass on my another fragment named locate_updatedstatus. I have a button on my locate_map fragment that has id to_update_status that would switch from locate_map to locate_updatedstatusat the same time would pass my ArrayList and display it as a listview on my locate_updatedstatus
There is no error upon bulding. However whenever I navigate to my locate_updatedstatus the app crashes.
Main activity. This is how I switch between fragments. I am using navigation drawer activity with container fragment
public void onSelectFragment(View v){
Fragment newFragment;
if(v == findViewById(R.id.to_update_status)){
newFragment = new locate_updatedstatus();
}
else{
newFragment = new locate_login();
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
locate_map fragment
public class locate_map extends Fragment implements Serializable{
public locate_map () {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_locate_map, container, false);
String[] updatedArr = {"display this", "also this"};
List<String> stringList = new ArrayList<String>(Arrays.asList(updatedArr));
Bundle bundle = new Bundle();
bundle.putSerializable("key", (Serializable) stringList);
return rootView;
}
}
locate_map xml button
<Button
android:id="#+id/to_update_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/check_images"
android:layout_marginTop="15dp"
android:text="Update Status"
android:width="340dp"
android:height="70dp"
android:onClick="onSelectFragment"
/>
locate_updatedstatus fragment
public class locate_updatedstatus extends Fragment implements Serializable {
public locate_updatedstatus() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_locate_updatedstatus, container, false);
ArrayList<String> stringList = (ArrayList<String>)getArguments().getSerializable("key");
ListView listSource = (ListView) rootView.findViewById(R.id.updates);
ArrayAdapter<String> listViewAdapter = new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_list_item_1,
stringList
);
listSource.setAdapter(listViewAdapter);
return rootView; // Inflate the layout for this fragment
}
}
locate_updatedstatus xml listview
<ListView
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_marginTop="60dp"
android:id="#+id/updates"
android:listSelector="#android:color/transparent"
/>
I would appreciate if the answers are in detail. I am beginner on android programming please bear with me.
logcat error
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.Serializable android.os.Bundle.getSerializable(java.lang.String)' on a null object reference at com.example.makati.sidebar.locate_updatedstatus.onCreateView(locate_updatedstatus.java:31)
All you need is bundle.putStringArray
String[] updatedArr = {"display this", "also this"};
bundle.putStringArray(KEY, updatedArr)
and
bundle.getStringArray(KEY)
In your's code you are not adding Bundle as argument to Fragment
Please use link to fix class constructor
below lines code just creating the bundle and adding arraylist to it. But there is nothing specified where it will be get used.
List<String> stringList = new ArrayList<String>(Arrays.asList(updatedArr));
Bundle bundle = new Bundle();
bundle.putSerializable("key", (Serializable) stringList);
Solution : hoping the first locate_login and then locate_updatedstatus fragments will be created in sequence.
locate_login fragment : trying to put content activity intent
List<String> stringList = new ArrayList<String>(Arrays.asList(updatedArr));
Bundle bundle = new Bundle();
bundle.putSerializable("key", (Serializable) stringList);
getActivity().getIntent().putExtras("key",bundle);
locate_upadtestatus fragment : get data from the activity intent
ArrayList<String> stringList = (ArrayList<String>)getActivity().getIntent().getExtras("key");
Related
I want to pass data from Activity to Fragment using Bundle (I used Bundle to passing data between 2 Fragment, and that's worked).
In my Activity I have a ListView, in the OnItemClickListener I want to open a new Fragment, and the Item, which clicked pass through the Activity to this Fragment. But the Item is null, so basically nothing is send to the Fragment.
Here is my Activity:
public class Jegyek extends AppCompatActivity {
View v;
DB mydb;
ListView listView;
private String teszt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jegyek);
listView = (ListView)findViewById(R.id.jegyekLista);
mydb = new DB(this);
final ArrayList<String> thelist = new ArrayList<>();
Cursor data = mydb.getTantargynev();
if (data.getCount() == 0) {
Toast.makeText(this, "Nincs jegyek hozzáadva", Toast.LENGTH_SHORT).show();
}
else {
while (data.moveToNext()) {
thelist.add(data.getString(0));
ListAdapter listadapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, thelist);
listView.setAdapter(listadapter);
}
listView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
teszt = thelist.get(i);
Bundle bundle = new Bundle();
bundle.putString("Tantárgy neve", teszt);
Toast.makeText(Jegyek.this, teszt, Toast.LENGTH_SHORT).show();
Fragment jegyekAllando = new jegyekAllando();
jegyekAllando.setArguments(bundle);
FragmentTransaction FragTan = getSupportFragmentManager().beginTransaction();
FragTan.replace(R.id.jegyekMenu, jegyekAllando);
ListView listaNezet = (ListView) findViewById(R.id.jegyekLista);
listaNezet.setVisibility(View.GONE);
FragTan.commit();
}
}
);
}
}
public String getTanNev () {
System.out.println("WARNING: "+ teszt);
return teszt;
}
}
And my Fragment:
public class jegyekAllando extends Fragment {
DB mydb;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_jegyek_allando, container, false);
Bundle bundle = new Bundle();
String tanNev = bundle.getStrin
g("Tantárgy neve");
Jegyek jegyAct = new Jegyek();
String tanNevv = jegyAct.getTanNev();
mydb = new DB(getActivity());
String jegyAtlag =String.valueOf(mydb.JegyekAtlaga(tanNev));
String jegyDarab =String.valueOf(mydb.JegyekDarabszama(tanNev));
return rootView;
}
}
When I realized, that the bundle is null, I try to pass that List Item through getter, so I changed my Fragment code for that:
Jegyek jegyek = new Jegyek();
String jegy = jegyek.getTanNev();
But that's not solved my problem, so I back to the Bundle, which also have some problem, but I can't find it. Intresting, that in the OnItemClickListener when I Toast the Item it's correct and works, but when I want to display in the console or pass to the Fragment, the value's is null.
From Activity you send data with intent as:
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
and in Fragment onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
Hope this helps
Please follow this example:
In your activity, Pass data like
Bundle bundle = new Bundle();
bundle.putString("test", "Test Data");
// set in your testFragment Arguments
TestFragment testFragment = new TestFragment();
testFragment.setArguments(bundle);
And Receive Data from your TestFragment Like
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String text = getArguments().getString("test");
return inflater.inflate(R.layout.fragment, container, false);
}
In fragment "jegyekAllando" you must get your string from onCreate() with Bundle data = getArguments(), but you create new bundle.
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);
}
My Fragment
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
return view;
}
public void sendItem(String item) {
btn.setText(item);
}
}
And in my activity
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
// Load fragment with data
CustomFrag frag = (CustomFrag) getSupportFragmentManager().findFragmentByTag("custFrag");
frag.sendItem(data);
}
I'm getting a nullpointer exception any time I attempt to use the views of my fragment. If I try to load the view inside the method as well, it will not work
i.e. inside sendItem()
btn = (Button)getView().findViewById(R.id.button1);
My layout (button_fragment) contains the button:
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Because you have executed the transaction does not mean that the fragment has actually created its view. Which is why btn is still null.
To pass data from the activity to the fragment, use the argument bundle:
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
Then, in onCreateView:
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments().getString("item"));
See this Best practice for instantiating a new Android Fragment question and the first answer.
The problem here is that the fragment's layout is not drawn yet when sendItem(...) is called. Which means btn is null at that point. Instead, this is how you're supposed to do it (see http://developer.android.com/guide/components/fragments.html):
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments.getString("item"));
return view;
}
}
And
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
}
Edit:
njzk2 was faster, but I hope the details I gave will help you further. In any case, the link he gave explains nicely why you should do it like that.
I'm having trouble refreshing an array adapter. When I'm testing the program on a phone it works well and refreshes perfectly when switching through fragments. The problem comes when I'm using a tablet and both fragments are up at once.
Here's my fragment code:
public class HistoryFragment extends Fragment {
private ArrayList<String> history = new ArrayList<String>();
private ArrayAdapter<String> arrayAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle data = getArguments();
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.history, container, false);
ListView view = (ListView) v.findViewById(R.id.list);
if(data != null){
history = data.getStringArrayList("history");
}
arrayAdapter = new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_list_item_1, history);
view.setAdapter(arrayAdapter);
return v;
}
public void setHistory(ArrayList<String> history) {
history.addAll(history);
arrayAdapter.notifyDataSetChanged();
}
}
Here's my activity code:
public class MainActivity extends Activity implements historyClickListener{
public static ArrayList<String> history = new ArrayList<String>();
CalcFragment mCalcFragment = new CalcFragment();
HistoryFragment mHistFragment = new HistoryFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.container) != null) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, mCalcFragment);
fragmentTransaction.commit();
}
}
#Override
public void sendHistory(ArrayList<String> history){
Fragment hf = getFragmentManager().findFragmentById(R.id.historyfrag);
if(hf != null){
mHistFragment.setHistory(history);
}else{
Bundle data = new Bundle();
data.putStringArrayList("history", history);
mHistFragment.setArguments(data);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, mHistFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
The sendHistory is an interface method in a calculator that help the calculator send the list of equations that have been done. Then in main activity if I'm using a tablet then all it does is setHistory which is a method in the history fragment. I believe the problem is that I'm not using arrayAdapter.notifyDataSetChanged() in the history fragment correctly. Can someone please help. Thanks!
You are setting the new data to a variable of the fragment not to the adapter who is the one who shows the data.
So you can:
Create a new ArrayAdapter with the new data and set it to the listview.
Extend ArrayAdapter, create a method that pass the new Data to the Adapter and then call notifyDataSetChanged().
this.history.addAll(history)? I see the same variable name for parameter and member variable.
I am using fragments in my application. This is my first fragment that simply inflate a xml file:
public class FragmentA extends SherlockFragment
{
Context myContext,appContext;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
myContext = getActivity();
appContext=getActivity().getApplicationContext();
arguments = getArguments();
doctor_id=arguments.getInt("doctor_id");
userType=arguments.getString("userType");
return inflater.inflate(R.layout.left_panel, container,false);
}
and this is the left_panel .xml, that contains a fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/titles"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
class="com.example.sample.ListFrag" />
</LinearLayout>
This is my ListFrag class:
public class ListFrag extends Fragment
{
Context myContext,appContext;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
layoutView = inflater.inflate(R.layout.activity_doctor_list,container);
myContext = getActivity();
appContext=getActivity().getApplicationContext();
arguments=getArguments();
int doctor_id=arguments.getInt("doctor_id");
}
}
I don't know how to pass Bundle arguments from FragmentA to ListFrag.
In your FragmentA fragment set the bundle as the argument.
Bundle args = new Bundle();
args.putInt("doctor_id",value);
ListFrag newFragment = new ListFrag ();
newFragment.setArguments(args);
In your ListFrag fragment get the bundle as
Bundle b = getArguments();
int s = b.getInt("doctor_id");
Fragment to Fragment set and get Argument:
Start Activity :
int friendId = 2; //value to pass as extra
i = new Intent(firstActivity, SecondActivity.class);
i.putExtra("friendsID", friendId);
firstActivity.startActivity(i);
SecondActivity:
Fragment_A mFragment_A = new Fragment_A();
mFragment_A.setArguments(getIntent().getExtras());
Fragment_A:
Bundle bundle = new Bundle();
String Item = getArguments().getString("friendsID");
bundle.putInt("friendsID", Integer.parseInt(Item));
// code
Fragment_B mFragment_B = new Fragment_B();
mFragment_B.setArguments(bundle);
Fragment_B:
Bundle bundle = getArguments();
int value = bundle.getInt("friendsID");
Log.e("value Fragment get Argument ", "friendsID :" + value);
this work for me,try this may be this sample help you.
Create a static method of ListFrag in ListFrag such as:
public static ListFrag newInstance(int doctorId) {
ListFrag frag = new ListFrag();
Bundle args = new Bundle();
args.putExtra("doctor_id", doctorId);
frag.setArguments(args);
return frag;
}
When you create a ListFrag from Fragment A, you would call:
Fragment frag = ListFrag.newInstance(this.doctor_id);
// use frag with getSupportChildFragmentManager();
You have two choice :
A. If i you have reference of your ListFragment
You can set target fragment for FragmentA by doing this :
in FragmentA this.setTargetFragment(yourListFragment);
then this.getTargetFragment().setArguments(yourBundle);
and in ListFragment get it back with in with this.getArguments();
B. The most logic way
I bet your fragment are in the same activity so she have references of them.
You can pass data to your activity from FragmentA and pass it to ListFragment
FragmentA --Data--> FragmentActivity --Data--> ListFragment