Android Studio从MainActivity访问Fragment方法

时间:2016-12-01 14:34:08

标签: android android-fragments

我在访问Fragment中的方法时遇到了一个非常烦人的问题。

我遇到错误

  

处理:com.crelix.crelix,PID:18913                                                                      java.lang.NullPointerException:尝试在空对象引用上调用虚方法'void com.crelix.crelix.ClickerFragment.refreshViews()'                                                                          在com.crelix.crelix.NavigationActivity.Refresh(NavigationActivity.java:530)                                                                          在com.crelix.crelix.NavigationActivity $ 1 $ 1.run(NavigationActivity.java:84)                                                                          在android.os.Handler.handleCallback(Handler.java:810)                                                                          在android.os.Handler.dispatchMessage(Handler.java:99)                                                                          在android.os.Looper.loop(Looper.java:189)                                                                          在android.app.ActivityThread.main(ActivityThread.java:5529)                                                                          at java.lang.reflect.Method.invoke(Native Method)                                                                          在java.lang.reflect.Method.invoke(Method.java:372)                                                                          在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:950)                                                                          在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)

我的碎片示例:

    package com.crelix.crelix;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import org.w3c.dom.Text;

public class ClickerFragment extends Fragment {

        public static ClickerFragment newInstance() {
            ClickerFragment fragment = new ClickerFragment();
        return fragment;
    }

    public ClickerFragment() {
    }

private TextView MoneyText;
private TextView MoneyPerTapTView;
private TextView BoxesText;
private TextView BoxesPerTapTView;
private ProgressBar progressBar;

MainHolder Main = new MainHolder();

public void refreshViews(){
    MoneyText.setText("Money: " +Main.Money[0]);
    MoneyPerTapTView.setText("$ " + Main.Money[1] + " per tap");
    BoxesText.setText("Boxes: " + Main.Boxes[0] + "/100");
    BoxesPerTapTView.setText("Points " + Main.Boxes[1] + " per tap");
    progressBar.setProgress(Main.Boxes[0]);
}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_clicker, container, false);
        MoneyText = (TextView) rootView.findViewById(R.id.MoneyText);
        MoneyPerTapTView = (TextView) rootView.findViewById(R.id.MoneyPerTapTView);
        BoxesText = (TextView) rootView.findViewById(R.id.BoxesText);
        BoxesPerTapTView = (TextView) rootView.findViewById(R.id.BoxesPerTapTView);
        progressBar = (ProgressBar) rootView.findViewById(R.id.progressBar);
        return rootView;
    }

}

我想从MainActivity访问它,如:

 public void Refresh()
{
    ClickerFragment ClickerFragment = (ClickerFragment) getSupportFragmentManager().findFragmentById(R.id.ClickerFragment);
    ClickerFragment.refreshViews();
}

我在这里添加我的片段

 public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    Fragment fragment = null;
    if (id == R.id.nav_clicker) {
        fragment = new ClickerFragment();
    } else if (id == R.id.nav_upgrades) {
        fragment = new UpgradeFragment();
    } else if (id == R.id.nav_warehouse) {
        fragment = new WarehouseFragment();
    } else if (id == R.id.nav_postservice) {
        fragment = new PostserviceFragment();
    } else if (id == R.id.nav_shop) {
        fragment = new ShopFragment();
    } else if (id == R.id.nav_market) {
        fragment = new MarketFragment();
    } else if (id == R.id.nav_workshop) {
        fragment = new WorkshopFragment();
    } else if (id == R.id.nav_garage) {
        fragment = new GarageFragment();
    } else if (id == R.id.nav_museum) {
        fragment = new MuseumFragment();
    } else if (id == R.id.nav_collections) {
        fragment = new CollectionsFragment();
    }
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();
    }
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

2 个答案:

答案 0 :(得分:1)

如果片段静态嵌入到活动中的XML中并且给定findFragmentById,则只能使用android:id

在您的情况下,看起来片段是在活动中的运行时动态添加的。因此,您可以通过调用 FragmentManager 上的findFragmentByTag来查找此片段按标记。在onNavigationItemSelected中,您需要更改为:

public boolean onNavigationItemSelected(MenuItem item) {
  // Handle navigation view item clicks here.
  int id = item.getItemId();
  String TAG = "";
  Fragment fragment = null;
  if (id == R.id.nav_clicker) {
    fragment = new ClickerFragment();
    TAG = "CLICKER_TAG";
  } else if (id == R.id.nav_upgrades) {
    fragment = new UpgradeFragment();
    TAG = "UPDATE_TAG";
  }
  // You need to add TAG to another fragment.
  ...

  getSupportFragmentManager().beginTransaction(). 
              replace(R.id.frame_container, fragment, TAG).
              commit();
  ...
  return true;
}

现在您可以按标签查找片段:

ClickerFragment clickerFragment  = (ClickerFragment) getSupportFragmentManager()
                                                    .findFragmentByTag("CLICKER_TAG");
// Now you have the fragment
// But remember to check if the fragment null
if(clickerFragment != null) {
  ClickerFragment.refreshViews();
}

Creating and Using Fragments了解详情。

答案 1 :(得分:0)

将您的MainActivity代码替换为

ClickerFragment ClickerFragment = (ClickerFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.frame_container);