2016-12-01 140 views
0

我在Fragment中訪問方法真的很煩人。Android Studio從MainActivity訪問Fragment方法

錯誤,我得到

過程:com.crelix.crelix,PID:18913 顯示java.lang.NullPointerException:嘗試調用虛擬方法「無效com.crelix.crelix.ClickerFragment.refreshViews() '在空對象引用 at com.crelix.crelix.NavigationActivity.Refresh(NavigationActivity.java:530) at com.crelix.crelix.NavigationActivity $ 1 $ 1.run(NavigationActivity.java:84) at android.os。 Handler.handleCallback(Handler.java:810) at android.os.Handler.dispatchMessage( Handler.java:99) at android.os.Looper.loop(Looper.java:189) at android.app.ActivityThread.main(ActivityThread.java:5529) at java.lang.reflect.Method.invoke(本地方法) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:950) at 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; 
} 
+1

可能的重複[什麼是NullPointerException,以及如何解決它?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) –

+0

這個問題是它不檢查片段是否可見或元素已經創建。查看片段的生命週期以進一步澄清,但其中的要點很可能是當您嘗試調用refreshView時,CreateView尚未激活。 – aminner

+0

@Manza編輯。 ;) – trakasi

回答

1

你只能使用findFragmentById如果片段靜態嵌入到活動中的XML和給予android:id

就你而言,它看起來像片段是在運行時在運行時動態添加的。所以你可以通過調用findFragmentByTagFragmentManager上通過標記來查找這個片段。在你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更多。

0

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

謝謝,但仍然是相同的錯誤:/ – trakasi

0

你可以做到這一點替換您MainActivity代碼的onNavigationItemSelected如果需要Fragments

Fragment fragment = null; 
String tag = null; 
if (id == R.id.nav_clicker) { 
    fragment = new ClickerFragment(); 
    tag = "ClickerFragment"; 
} 
... 
if (fragment != null) { 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    //Add a tag parameter 
    fragmentManager.beginTransaction() 
     .replace(R.id.frame_container, fragment, tag).commit(); 
} 

在你Refresh方法做到這一點

public void Refresh() 
{ 
    ClickerFragment ClickerFragment = (ClickerFragment) getSupportFragmentManager().findFragmentByTag("ClickerFragment"); 
    ClickerFragment.refreshViews(); 
} 
相關問題