问题
I have been spending my time for several days with this question and getting same error. I have been trying to pass object between fragments which are held in action bar. Please tell me where i make the mistake. Here my code:
package com.restaurantexample.fragment;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.restaurantexample.adapter.MenuItemAdapter;
import com.restaurantexample.listener.OnMenuItemPressListener;
import com.restaurantexample.main.R;
import com.restaurantexample.menuitems.BaseOfMenuItems;
public class DrinksFragment extends Fragment implements OnItemClickListener {
private List<BaseOfMenuItems> drinks;
private BaseOfMenuItems cocaCola, fanta, pepsi, mirinda, sevenUp, juice,
water, lemonade, mohito;
private ListView lv;
private MenuItemAdapter adapter;
private int layoutId;
private int productId;
private int volumeId;
private int priceId;
private int imgId;
private OnMenuItemPressListener menuItemListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View drinksView = inflater.inflate(R.layout.drinks_fragment, container,
false);
drinks = new ArrayList<BaseOfMenuItems>();
cocaCola = new BaseOfMenuItems("Кока кола", "330 мл", 50,
R.drawable.ic_launcher);
drinks.add(cocaCola);
fanta = new BaseOfMenuItems("Фанта", "330 мл", 50,
R.drawable.ic_launcher);
drinks.add(fanta);
pepsi = new BaseOfMenuItems("Пепси", "330 мл", 50,
R.drawable.ic_launcher);
drinks.add(pepsi);
mirinda = new BaseOfMenuItems("Миринда", "330 мл", 50,
R.drawable.ic_launcher);
drinks.add(mirinda);
sevenUp = new BaseOfMenuItems("7 уп", "330 мл", 50,
R.drawable.ic_launcher);
drinks.add(sevenUp);
juice = new BaseOfMenuItems("Сок", "250 мл", 150,
R.drawable.ic_launcher);
drinks.add(juice);
water = new BaseOfMenuItems("Негазированная вода", "500 мл", 40,
R.drawable.ic_launcher);
drinks.add(water);
lemonade = new BaseOfMenuItems("Домашний лимонад", "300 мл", 150,
R.drawable.ic_launcher);
drinks.add(lemonade);
mohito = new BaseOfMenuItems("Мохито безалкогольный", "300 мл", 200,
R.drawable.ic_launcher);
drinks.add(mohito);
layoutId = R.layout.drinks_list;
productId = R.id.product;
volumeId = R.id.volume;
priceId = R.id.price;
imgId = R.id.imgDrinks;
lv = (ListView) drinksView.findViewById(R.id.drinkslistview);
adapter = new MenuItemAdapter(getActivity(), drinks, layoutId,
productId, volumeId, priceId, 0, imgId);
lv.setAdapter(adapter);
return drinksView;
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
menuItemListener = (OnMenuItemPressListener) getActivity();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
lv.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
**menuItemListener.onMenuItemPressed(drinks.get(arg2));**
}
}
Here is second fragment:
package com.restaurantexample.fragment;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import com.restaurantexample.adapter.MenuItemAdapter;
import com.restaurantexample.main.R;
import com.restaurantexample.menuitems.BaseOfMenuItems;
public class BasketFragment extends Fragment {
private List<BaseOfMenuItems> menuItem;
private ListView lv;
private MenuItemAdapter adapter;
private int layoutId;
private int productId;
private int portionId;
private int priceId;
private int imgId;
private View basketView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
basketView = inflater.inflate(
R.layout.basket_fragment, container, false);
return basketView;
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
setRetainInstance(true);
layoutId = R.layout.basket_list;
productId = R.id.basketProduct;
portionId = R.id.portion;
priceId = R.id.basketPrice;
imgId = R.id.imgBasket;
menuItem = new ArrayList<BaseOfMenuItems>();
lv = (ListView) activity.findViewById(R.id.basketlistview);
adapter = new MenuItemAdapter(getActivity(), menuItem, layoutId,
productId, 0, priceId, portionId, imgId);
lv.setAdapter(adapter);
}
public void setMenuItem(BaseOfMenuItems mi) {
menuItem.add(mi);
}
}
And activity class:
package com.restaurantexample.main;
import com.restaurantexample.main.R;
import com.restaurantexample.menuitems.BaseOfMenuItems;
import com.restaurantexample.fragment.BasketFragment;
import com.restaurantexample.fragment.DiscountFragment;
import com.restaurantexample.fragment.MenuFragment;
import com.restaurantexample.listener.OnMenuItemPressListener;
import com.restaurantexample.listener.RestaurantTabListener;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar.Tab;
import android.view.Menu;
import android.view.MenuInflater;
public class RestaurantMainPage extends ActionBarActivity implements OnMenuItemPressListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actBar = getSupportActionBar();
actBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actBar.setDisplayShowTitleEnabled(true);
Tab restMenuTab = actBar.newTab();
restMenuTab.setText("Меню");
restMenuTab.setTabListener(new RestaurantTabListener<MenuFragment>(this, "menu", MenuFragment.class));
actBar.addTab(restMenuTab);
Tab discountTab = actBar.newTab();
discountTab.setText("%");
discountTab.setTabListener(new RestaurantTabListener<DiscountFragment>(this, "discount", DiscountFragment.class));
actBar.addTab(discountTab);
Tab basketTab = actBar.newTab();
basketTab.setText("Корзина");
basketTab.setTabListener(new RestaurantTabListener<BasketFragment>(this, "basket", BasketFragment.class));
actBar.addTab(basketTab);
if (savedInstanceState != null) {
int savedIndex = savedInstanceState.getInt("index", 0);
getSupportActionBar().setSelectedNavigationItem(savedIndex);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putInt("index", getSupportActionBar().getSelectedNavigationIndex());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.restaurant_main_page, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public void onMenuItemPressed(BaseOfMenuItems mi) {
// TODO Auto-generated method stub
BasketFragment bf = (BasketFragment) getSupportFragmentManager().findFragmentById(R.id.basketlistview);
**bf.setMenuItem(mi);**
}
}
My custom adapter:
package com.restaurantexample.adapter;
import java.util.List;
import com.restaurantexample.menuitems.BaseOfMenuItems;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MenuItemAdapter extends BaseAdapter{
private Context context;
private List<BaseOfMenuItems> list;
private LayoutInflater inflater;
private int layoutId;
private int productId;
private int amountId;
private int priceId;
private int portionId;
private int imgId;
public MenuItemAdapter(Context context, List<BaseOfMenuItems> list,
int layoutId, int productId, int amountId, int priceId, int portionId, int imgId) {
this.context = context;
this.list = list;
this.layoutId = layoutId;
this.productId = productId;
this.amountId = amountId;
this.priceId = priceId;
this.portionId = portionId;
this.imgId = imgId;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
TextView product, volume, price, portion;
ImageView img;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(layoutId, parent, false);
volume = (TextView) itemView.findViewById(amountId);
volume.setText(list.get(position).getAmount());
product = (TextView) itemView.findViewById(productId);
product.setText(list.get(position).getProduct());
price = (TextView) itemView.findViewById(priceId);
price.setText("" + list.get(position).getPrice());
img= (ImageView) itemView.findViewById(imgId);
img.setImageResource(list.get(position).getImage());
return itemView;
}
}
I showed lines in bold where i get error. And this the logcat
10-05 00:40:24.187: E/AndroidRuntime(273): FATAL EXCEPTION: main
10-05 00:40:24.187: E/AndroidRuntime(273): java.lang.NullPointerException
10-05 00:40:24.187: E/AndroidRuntime(273): at com.restaurantexample.main.RestaurantMainPage.onMenuItemPressed(RestaurantMainPage.java:68)
10-05 00:40:24.187: E/AndroidRuntime(273): at com.restaurantexample.fragment.DrinksFragment.onItemClick(DrinksFragment.java:104)
10-05 00:40:24.187: E/AndroidRuntime(273): at android.widget.AdapterView.performItemClick(AdapterView.java:284)
10-05 00:40:24.187: E/AndroidRuntime(273): at android.widget.ListView.performItemClick(ListView.java:3382)
10-05 00:40:24.187: E/AndroidRuntime(273): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1696)
10-05 00:40:24.187: E/AndroidRuntime(273): at android.os.Handler.handleCallback(Handler.java:587)
10-05 00:40:24.187: E/AndroidRuntime(273): at android.os.Handler.dispatchMessage(Handler.java:92)
10-05 00:40:24.187: E/AndroidRuntime(273): at android.os.Looper.loop(Looper.java:123)
10-05 00:40:24.187: E/AndroidRuntime(273): at android.app.ActivityThread.main(ActivityThread.java:4627)
10-05 00:40:24.187: E/AndroidRuntime(273): at java.lang.reflect.Method.invokeNative(Native Method)
10-05 00:40:24.187: E/AndroidRuntime(273): at java.lang.reflect.Method.invoke(Method.java:521)
10-05 00:40:24.187: E/AndroidRuntime(273): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-05 00:40:24.187: E/AndroidRuntime(273): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-05 00:40:24.187: E/AndroidRuntime(273): at dalvik.system.NativeStart.main(Native Method)
回答1:
In onAttach() function of the first fragment, I have some doubt about initializing the callback menuItemListener. The onAttach() function is called at the very first in the order of sequence of calls to initialize a fragment. getActivity() may not be ready yet to return the associated activity.
Why don't you just initialize like this:
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
menuItemListener = (OnMenuItemPressListener) activity;
}
activity itself is available in the parameter of the function. No need to call another function to get it.
来源:https://stackoverflow.com/questions/19192871/having-trouble-passing-object-between-fragments