Soru & Cevap

Fragment lar arasında nesne geçişi

05.10.2013 - 03:06

Geliştirdiğim uygulamada bir fragment tan diğer bir fragment a nesne aktarırken NullPointerException hatası alıyorum. Fragment lar ActionBar içinde navigasyon modunda bulunuyorlar. Nerede hata yaptığımı gösterebilirseniz sevinirim. Yazdığım kod:

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));
    }
}

Nesneyi aktarmak istediğim 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);

    }
}


Activity sınıfı;

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);
    }
    
}


Adapter sınıfı;

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 list.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        TextView product, volume, price, portion;
        ImageView img;
        
        View itemView = convertView;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        
        if(convertView == null) {
            itemView = inflater.inflate(layoutId, parent, false);
        }
        
        if (portionId == 0) {
            volume = (TextView) itemView.findViewById(amountId);
            volume.setText(list.get(position).getAmount());
        } else if (amountId == 0){
            portion = (TextView) itemView.findViewById(portionId);
            portion.setText(list.get(position).getPortion());
        }
        
        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;
    }
    
}


Ve aldığım hata çıktısı;

10-05 10:11:17.674: E/AndroidRuntime(275): FATAL EXCEPTION: main
10-05 10:11:17.674: E/AndroidRuntime(275): java.lang.NullPointerException
10-05 10:11:17.674: E/AndroidRuntime(275):   at com.restaurantexample.fragment.DrinksFragment.onItemClick(DrinksFragment.java:103)
10-05 10:11:17.674: E/AndroidRuntime(275):     at android.widget.AdapterView.performItemClick(AdapterView.java:284)
10-05 10:11:17.674: E/AndroidRuntime(275):     at android.widget.ListView.performItemClick(ListView.java:3382)
10-05 10:11:17.674: E/AndroidRuntime(275):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:1696)
10-05 10:11:17.674: E/AndroidRuntime(275):     at android.os.Handler.handleCallback(Handler.java:587)
10-05 10:11:17.674: E/AndroidRuntime(275):     at android.os.Handler.dispatchMessage(Handler.java:92)
10-05 10:11:17.674: E/AndroidRuntime(275):     at android.os.Looper.loop(Looper.java:123)
10-05 10:11:17.674: E/AndroidRuntime(275):     at android.app.ActivityThread.main(ActivityThread.java:4627)
10-05 10:11:17.674: E/AndroidRuntime(275):     at java.lang.reflect.Method.invokeNative(Native Method)
10-05 10:11:17.674: E/AndroidRuntime(275):     at java.lang.reflect.Method.invoke(Method.java:521)
10-05 10:11:17.674: E/AndroidRuntime(275):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-05 10:11:17.674: E/AndroidRuntime(275):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-05 10:11:17.674: E/AndroidRuntime(275):     at dalvik.system.NativeStart.main(Native Method)

Bir haftadır bu sorunu çözmeye çalışıyorum. Yardımlarınız için şimdiden teşekkürler.

69 Görüntülenme

4 Cevap

Sitedeki sorulara cevap verebilmek için giriş yapın ya da üye olun.

Profile picture for user yasinkafadar
yasinkafadar
08.10.2013 - 07:17
Selam Ersan, Yazmış olduğun projede kritik bir bilgi yoksa gondermen mumkun mudur? Oyle daha rahat yardimci olabilirim. Bir önceki cevabimda listener null kalmıştı sorun onunla alakli degil sanirim.
Profile picture for user ersanmaz
ersanmaz
08.10.2013 - 12:09

Merhaba Yasin,

Öncelikle cevabın için çok teşekkürler. Buradan cevap alma ümidimi kesmiştim. Kodu android developer kaynağındaki dizaynı baz alarak bu şekilde yazdım.

Önerini uyguladım ancak listeyi global yaptığımda ve diğer fragment tan çağırdığımda DrinksFragment a cast etmeye çalışıyor ve hata alıyorum. Normalde javada böyle bir hata almazken burada neden bu hatayı veriyor anlamış değilim.

Nette baktığım tüm örneklerde fragmentler arası geçişler için bu dizaynı uygulamışlar. Açıkçası ben neden nullpointerexception hatası alıyorum hala çözmüş değilim.

Tekrar yardımın için teşekkürker.

Profile picture for user yasinkafadar
yasinkafadar
06.10.2013 - 06:41

Ayrıca bu içecek listesine ekleme işini activity'nin onCreate'inde yaparım.

Profile picture for user yasinkafadar
yasinkafadar
06.10.2013 - 06:40

Selam Ersan,

Bu yazdığın kodlardan okuduğum kadarıyla DrinksFragment'ın içinde tanımladığın menuItemListener null olarak kalmış. onAttach'in içinde referens'ını aldığın yeri commentlemişsin en son buraya koyduğun kodda.

Ben senin yerinde olsam drinks listesini global olarak tutarım. Çünkü bu listeyi sadece o fragment'da değil global olarak kullanıyorsun sanırım. Sadece aktif olan içeceğin index'ini yine global olarak tutman senin işini çözecektir sanırım.