从FragmentStatePagerAdapter

时间:2017-08-02 17:19:24

标签: android nullpointerexception android-viewpager fragment facebook-login

我在Android Studio上有一个项目,我遇到了这种情况。主要想法,我的应用程序显示使用向导模型的订单步骤。我使用viewpager和FragmentStatePagerAdapter。我有一些片段,一个片段(第6个片段)是用户的联系人,在用户未登录时显示。

用户可以登录此片段(使用Facebook)。登录成功后,应删除此片段。我试图删除此片段,但发生错误。它告诉我在尝试获取getActivity()值时(在第7个片段)有一个空指针异常。我不知道为什么会出现这个错误,因为当用户没有登录第6个片段时,可以正常使用。

这是我的代码

MyAcitivity.java

public class MyActivity extends AppCompatActivity {

    ClassName className = new ClassName ();

    ProgressDialog progressDialog;
    ProgressBar progressBar;
    ViewPager viewPager;
    MyActivity.PagerAdapter adapter;

    String type;


    ArrayList<Addons> listAddons = new ArrayList<Addons>();
    boolean changed = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        progressDialog = new ProgressDialog(this);


        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        progressBar = (ProgressBar) findViewById(R.id.progress_booking);
        viewPager = (ViewPager) findViewById(R.id.pager);
        viewPager.setPagingEnabled(false);
        adapter = new PagerAdapter(this, getSupportFragmentManager());
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new android.support.v4.view.ViewPager.SimpleOnPageChangeListener(){
            @Override
            public void onPageSelected(int position) {
                updateToolbar();
            }
        });

        updateToolbar();
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()){
            case android.R.id.home:
                onBackPressed();
                break;
        }
        return true;
    }

    @Override
    public void onBackPressed() {

    }

    public void updateToolbar() {
        int position = viewPager.getCurrentItem();
        getSupportActionBar().setTitle(adapter.getTitle(position));
        bookingProgressBar.setVisibility(View.VISIBLE);
        bookingProgressBar.setMax(adapter.getCount());
        bookingProgressBar.setProgress(position+1);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.close);

    }

    public class PagerAdapter extends FragmentStatePagerAdapter {

        List<Fragment> items = new ArrayList<>();
        List<String> titles = new ArrayList<>();
        List<Boolean> instantiated = new ArrayList<>();

        public PagerAdapter(Activity activity, FragmentManager fm) {
            super(fm);
            items.add(new 1stFragment());
            items.add(new 2ndFragment());
            items.add(new 3rdFragment());
            items.add(new 4thFragment());
            items.add(new 5thFragment());
            items.add(new 6thFragment());
            items.add(new 7thFragment());
            items.add(new 8thFragment());

            titles.add(activity.getString(R.string.1));
            titles.add(activity.getString(R.string.2));
            titles.add(activity.getString(R.string.3));
            titles.add(activity.getString(R.string.4));
            titles.add(activity.getString(R.string.5));
            titles.add(activity.getString(R.string.6));
            titles.add(activity.getString(R.string.7));
            titles.add(activity.getString(R.string.8));

            instantiated.add(false);
            instantiated.add(false);
            instantiated.add(false);
            instantiated.add(false);
            instantiated.add(false);
            instantiated.add(false);
            instantiated.add(false);
            instantiated.add(false);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            super.destroyItem(container, position, object);
            instantiated.set(position, false);
        }

        @Override
        public void finishUpdate(ViewGroup container) {
            super.finishUpdate(container);
            if(!instantiated.get(viewPager.getCurrentItem())){

                ((MyBaseFragment) items.get(viewPager.getCurrentItem())).setListAddons(listAddons);
                ((MyBaseFragment) items.get(viewPager.getCurrentItem())).setClassName(className);
                ((MyBaseFragment) items.get(viewPager.getCurrentItem())).instantiate();
                instantiated.set(viewPager.getCurrentItem(), true);
            }
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

        @Override
        public Fragment getItem(int position) {
            return items.get(position);
        }

        public String getTitle(int position){
            return titles.get(position);
        }

        @Override
        public int getCount() {
            return items.size();
        }

        public void removeContact(){
            items.remove(5);
            titles.remove(5);
            instantiated.remove(5);
            notifyDataSetChanged();
            updateToolbar();
            ((MyBaseFragment) items.get(viewPager.getCurrentItem())).setListAddons(listAddons);
            ((MyBaseFragment) items.get(viewPager.getCurrentItem())).setClassName(className);
            ((MyBaseFragment) items.get(viewPager.getCurrentItem())).instantiate();
        }
    }

}

6thFragment 请首先关注onCompleted回调..

    public class 6thFragment extends MyBaseFragment {

        EditText emailEditText;
        private CallbackManager callbackManager;

        public 6thFragment() {
            // Required empty public constructor
        }


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            final View view = inflater.inflate(R.layout.6fragment_layout, container, false);
            emailEditText = (EditText) view.findViewById(R.id.editText_email);

            if((new SessionPreference(getActivity())).isLoggedIn()){
                ((MyActivity.PagerAdapter)((ViewPager) view.getParent()).getAdapter()).removeContact();
            }
            callbackManager = CallbackManager.Factory.create();

            LoginButton loginButton = (LoginButton) view.findViewById(R.id.login_button);
            loginButton.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            loginButton.setFragment(this);
            loginButton.setReadPermissions(Arrays.asList("public_profile, email"));
            loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    GraphRequest request = GraphRequest.newMeRequest(
                            loginResult.getAccessToken(),
                            new GraphRequest.GraphJSONObjectCallback() {

                                @Override
                                public void onCompleted(JSONObject object, GraphResponse response) {

//**HERE THE MAIN QUESTION, AFTER USER SUCCESS LOGIN USING FACEBOOK**//
// **6th fragment should be removed**
                                    ((MyActivity.PagerAdapter)((ViewPager) view.getParent()).getAdapter()).removeContact();
                                }
                            });
                    Bundle parameters = new Bundle();
                    parameters.putString("fields", "id,name,email");
                    request.setParameters(parameters);
                    request.executeAsync();
                }

                @Override
                public void onCancel() {
                    Toast.makeText(getActivity(), "Login is canceled", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onError(FacebookException exception) {
                    Toast.makeText(getActivity(), "Login is error", Toast.LENGTH_SHORT).show();
                }
            });

            return view;
        }

        @Override
        public void instantiate() {
            //somecode
        }

        @Override
        public boolean isValid() {
            //some code
        }

        @Override
        public boolean isChanged() {
            return emailEditText.getText().toString().trim().equals(generalCleaning.getEmail());
        }

        @Override
        public ClassName getClassName() {
            ///some code
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            callbackManager.onActivityResult(requestCode, resultCode, data);
        }
    }

然后是 7thFragment 请首先关注setPrice方法

public class 7thFragment extends MyBaseFragment implements View.OnClickListener{

        String planStr, planStrOld;

        LinearLayout weeklyLinearLayout, biweeklyLinearLayout, onetimeLinearLayout;
        RadioButton weeklyRadioButton, biweeklyRadioButton, onetimeRadioButton;

        RadioButton prevChecked;

        ProgressDialog progressDialog;

        TextView priceTextView, dateTextView, timeTextView;

        SimpleDateFormat dateFormater = new SimpleDateFormat("EEEE, MMM d", Locale.getDefault()),
                timeFormater = new SimpleDateFormat("HH:mm", Locale.getDefault());

        public 7thFragment() {
            // Required empty public constructor
        }


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.7th_layout, container, false);

            progressDialog = new ProgressDialog(getActivity());

            //codes

            return view;
        }

        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            if(isVisibleToUser){
                setPrice();
                setRadioButton();
            }
        }


        @Override
        public void instantiate() {
            if(isAdded()){
                setPrice();
                setRadioButton();
            }
        }

        @Override
        public boolean isValid() {
            //codes
        }

        @Override
        public boolean isChanged() {
            if(planStr.equalsIgnoreCase(planStrOld)){
                return true;
            }else {
                return false;
            }
        }

        @Override
        public ClassName getClassName() {
            //code
        }

        @Override
        public void onClick(View view) {
            prevChecked.setChecked(false);

            if(view instanceof RadioButton) {
                ((RadioButton) view).setChecked(true);
                prevChecked = ((RadioButton) view);
            }else {
                LinearLayout linearLayout = (LinearLayout) view;
                ((RadioButton) linearLayout.getChildAt(0)).setChecked(true);
                prevChecked = ((RadioButton) linearLayout.getChildAt(0));
            }

            String plan;
            if(prevChecked.getId()==R.id.plan_weekly){
                plan = getString(R.string.weekly);
            }else if(prevChecked.getId()==R.id.plan_biweekly){
                plan = getString(R.string.biweekly);
            }else{
                plan = getString(R.string.one_time);
            }

            getSideBar(plan);

        }

        private void setPrice(){
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                String date = dateFormater.format(sdf.parse(className.getBooked_date()));
                String time = timeFormater.format(sdf.parse(className.getBooked_date()));

                dateTextView.setText(date);
//HERE THE MAIN ERROR, I GET NULL POINTER EXCEPTION (at getActivity())
                timeTextView.setText(time+" - "+getActivity().getString(R.string.general_cleaning_duration_value, generalCleaning.getDuration()));

                priceTextView.setText(className.getPrice());

            } catch (ParseException pe) {
                pe.printStackTrace();
            }
        }

        private void setRadioButton(){
            //codes
        }


    }

希望大家都理解我的问题,谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

我不知道为什么mu问题得到这么多的支持。

我找到了答案,我将此代码添加到我的7thFragment中,并将myActivity替换为getActivity()。一切正常。

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        myActivity = (MyActivity) context;
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            myActivity = (MyActivity) activity;
        }
    }

希望这能帮到你