1

フラグメントは、ナビゲーション・バーではこれまでのように、ボトム・ナビゲーション・バーの一部です。しかし、フラグメント1からフラグメント2にデータを渡そうとすると、アプリケーションがクラッシュします。また、私はこの例でgoogleによって与えられた例を使用していますlinkインタフェース経由のフラグメント間の通信

私は次のコードを使用すると私は非推奨の警告を与える!

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

だから私は代わりに活動のCONTEXTを使用しています以下がクラッシュした私のコードです:

MainActivity

import android.support.annotation.NonNull; 
import android.support.design.widget.BottomNavigationView; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentTransaction; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.TextView; 
import com.br.tron.bottombar.RadioFragment; 
import com.br.tron.bottombar.StreamFragment; 
import com.br.tron.bottombar.InfoFragment; 

public class MainActivity extends AppCompatActivity implements RadioFragment.OnNameSetListener { 

    BottomNavigationView bottomNavigationView; 
    private Fragment fragment; 
    private FragmentManager fragmentManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     fragmentManager = getSupportFragmentManager(); 
     fragment = new RadioFragment(); 
     final FragmentTransaction transaction = fragmentManager.beginTransaction(); 
     transaction.add(R.id.main_container, fragment).commit(); 

     bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationBar); 
     bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener(){ 
      @Override 
      public boolean onNavigationItemSelected(@NonNull MenuItem item) { 

       switch (item.getItemId()) { 
        case R.id.nav_button_one: 
         fragment = new RadioFragment(); 
         break; 
        case R.id.nav_button_two: 
         fragment = new StreamFragment(); 
         break; 
        case R.id.nav_button_three: 
         fragment = new InfoFragment(); 
         break; 
       } 
       final FragmentTransaction transaction = fragmentManager.beginTransaction(); 
       transaction.replace(R.id.main_container, fragment).commit(); 
       return true; 
      } 
     }); 
    } 

    public void performStreamClick(){ 
     View view = bottomNavigationView.findViewById(R.id.nav_button_two); 
     view.performClick(); 
    } 

    @Override 
    public void setUrl(String url) { 
     StreamFragment frag=(StreamFragment) getSupportFragmentManager().findFragmentByTag("frag"); 
     frag.getUrl(url); 
    } 
} 

RadioFragment(データが存在Fragment1)

import android.app.Activity; 
import android.content.Context; 
import android.support.v4.app.Fragment; 
import android.os.Bundle; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentTransaction; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 

public class RadioFragment extends Fragment implements Button.OnClickListener { 

    Button buttonman; 
    View rootView; 
    String url; 
    Activity a; 
    OnNameSetListener onNameSetListener; 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     if (context instanceof Activity) { 
      a = (Activity) context; 
      try{ 
       onNameSetListener=(OnNameSetListener) context; 
      } 
      catch (Exception e){} 
     } 
    } 

    public RadioFragment(){ 
    }; 

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

     rootView = inflater.inflate(R.layout.fragment_player, container, false); 
     buttonman = (Button)rootView.findViewById(R.id.buttonman); 
     buttonman.setOnClickListener(this); 
     return rootView; 
    } 

    @Override 
    public void onClick(View v) { 
     /*Fragment fragment = new StreamFragment(); 
     FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
     fragmentTransaction.replace(R.id.main_container, fragment); 
     fragmentTransaction.addToBackStack(null); 
     fragmentTransaction.commit();*/ 
     url="www.idontknow.com"; 
     onNameSetListener.setUrl(url); 
     ((MainActivity)a).performStreamClick(); 
    } 

    public interface OnNameSetListener 
    { 
     public void setUrl(String url); 
    } 
} 

StreamFragment(fragment2私は-from fragment1データを送信したい場合)

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.TextView; 

public class StreamFragment extends Fragment { 

    TextView textViewStream; 

    public StreamFragment(){}; 

    @Override 
    public View onCreateView(final LayoutInflater inflater,final ViewGroup container,final Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_stream, container, false); 

    } 

    public void getUrl(String url) 
    { 
     textViewStream.setText(url); 
    } 

} 

LOGCAT

01-06 20:10:23.023 3744から3744 /com.br.tron.bottombar E/AndroidRuntime:致命的除外:メイン プロセス:com.br.tron.bottombar、PID:3744 java.lang.NullPointerException:NULLオブジェクト参照で仮想メソッド 'void com.br.tron.bottombar.StreamFragment.getUrl(java.lang.String)'を呼び出そうとしました com.br.tron.bottombar.MainActivity.setUrl (MainActivity.java:64) at com.br.tron.bottombar.RadioFragment.onClick(RadioFragment.java:61) at android.view.View.performClick(View.java:5201) android.view.View $ PerformClick.run(View.java:21209) とandroid.os.Handler.handleCallback(Handler.java:739) とandroid.os.Handler.dispatchMessage(Handler.java:95) とandroid.os.Looper .loop(Looper.java:148) android.app.ActivityThre ad.main(ActivityThread.java:5525) at java.lang.reflect.Method.invoke(ネイティブメソッド) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:730) at com .android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 01-06 20:10:24.663 3744-3744 /? I /プロセス:シグナルを送信します。 PID:3744 SIG:9

答えて

0

StreamFragmentフラグメントのtextViewStreamを初期化する必要があります。

+0

?それは良いですか? –

+0

あなたにいくつかの情報を追加してください。なぜこのソリューションがうまくいくのか、そしてなぜOPの方法ではないのかを説明してください。 –

3

fragタグは登録しないでください。あなたのMainActivityで

は変更:あなたがあなたのレイアウトを膨らま後TextViewStream変数を設定したことがないあなたのStreamFragmentクラス内でそれに加えて

final FragmentTransaction transaction = fragmentManager.beginTransaction(); 
transaction.add(R.id.main_container, fragment, "frag").commit(); 
... 
final FragmentTransaction transaction = fragmentManager.beginTransaction(); 
transaction.replace(R.id.main_container, fragment, "frag").commit(); 
... 

@Override 
public View onCreateView(final LayoutInflater inflater,final ViewGroup container,final Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_stream, container, false); 
    textViewStream = (TextView) view.findViewById(R.id.ID_GOES_HERE); 
    return view; 
} 

編集:さらにエラー

あなたはMainActivity.setUrlに入るフラグメントがStreamFragmentあるかどうかをチェックしていないので、あなたがClassCastExceptionを取得しています。また、3種類すべてのカスタムフラグメントにfragタグを登録しているため、失敗していると考えられます。ここでは、さらに解決策があります:

 fragment = new RadioFragment(); 
     final FragmentTransaction transaction = fragmentManager.beginTransaction(); 
     transaction.add(R.id.main_container, fragment, "radio_fragment").commit(); 
     ... 

     @Override 
     public boolean onNavigationItemSelected(@NonNull MenuItem item) { 

      switch (item.getItemId()) { 
       String tag = ""; 
       case R.id.nav_button_one: 
        fragment = new RadioFragment(); 
        tag = "radio_fragment"; 
        break; 
       case R.id.nav_button_two: 
        fragment = new StreamFragment(); 
        tag = "stream_fragment"; 
        break; 
       case R.id.nav_button_three: 
        fragment = new InfoFragment(); 
        tag = "info_fragment"; 
        break; 
      } 
      final FragmentTransaction transaction = fragmentManager.beginTransaction(); 
      transaction.replace(R.id.main_container, fragment, tag).commit(); 
      return true; 
     } 

setUrlにタグ文字列に適切な変更を行います。

StreamFragment frag=(StreamFragment) getSupportFragmentManager().findFragmentByTag("stream_fragment"); 
if (frag != null) frag.getUrl(url); 
+1

まだクラッシュメイト私はsivaが既にそれを指摘し、あなたの提案に従ってMainActivityを修正したので、textViewStreamを初期化しました –

+0

@ user3599100 stacktraceはまだ同じですか?新しいスタックトレースを投稿してください。 – asadmshah

+0

新しいスタックトレース - >とjava.lang.ClassCastException:RadioFragmentは大体このコードが指されStreamFragment にキャストすることはできません - > '@Override 公共ボイドてsetURL(文字列のURL){ StreamFragment FRAG =(StreamFragment)getSupportFragmentManager() .findFragmentByTag( "frag"); frag.getUrl(url); } ' –

0

現在の解答キーの両方をお使いのクラッシュ問題についてで。私はあなたの主な質問を世話することを期待しています。 @asadmshahはあなたの次の問題の世話をしたようです。彼の答弁&を受け入れることを確認してください。

Googleのサンプルコードを使用した警告に関しては、新しいフラグメントを作成するように指示した場合、ASが現在あなたに与えるものがここにあります。

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    if (context instanceof OnFragmentInteractionListener) { 
     mListener = (OnFragmentInteractionListener) context; 
    } else { 
     throw new RuntimeException(context.toString() 
       + " must implement OnFragmentInteractionListener"); 
    } 
} 

これは、アタッチするアクティビティが、フラグメントで定義したインターフェイスを実装していることを確認することです。

インターフェイスの主題については、すべてのフラグメントからアクティビティへの通信は、それを介して行う必要があります。インターフェースを通じてperformStreamClick()に電話する方法を見つける方が良いでしょう。 (私は数ヶ月前に始まったアプリでこの同じミスを犯したことに気がついたが、ただちに終了している:)

最後に、FYIだけで、getActivity()でフラグメントのアタッチされたアクティビティを取得できます。

EDIT: 第1回、あなたの現在のコードを見てください。私はアサドが答えに入れたことを多かれ少なかれ持っていると思います。また、期待される行動は何ですか? RadioFragmentで選択してStreamFragmentに置き換えたと思います。つまり、両方のフラグメントがナビゲーションバー全体を取り、同時に存在しません。これが間違っている場合は、私に知らせてください。

setUrl()performStreamClick()を以前と同じ順序で呼び出している場合は、その名前でフラグメントを作成したことがないため、nullが返されます。まだ作成していないフラグメントは見つかりません。

実際にこれを設定して自分でテストするのではなく、URL変数をsetUrl()に保存してからクリックリスナーでURLを保存すると、StreamFragmentに渡します。

あなたは

 Bundle args = new Bundle(); 
     args.putInt(ArticleFragment.ARG_POSITION, position); 
     newFragment.setArguments(args); 

(当然、代わりに例のintのあなたのURL文字列を扱う)ことを行うために土地を選定しましたリンクのセクション「フラグメントにメッセージを配信」を参照してください。存在するはずのフラグメントを検索する際に

はまた、ヌルを処理するために、悪い考えではありませんすでに

StreamFragment frag=(StreamFragment) getSupportFragmentManager().findFragmentByTag("stream_frag"); 
    if(frag == null) { 
     final FragmentTransaction transaction = fragmentManager.beginTransaction(); 
     StreamFragment fragment = new StreamFragment(); 
     transaction.replace(R.id.main_container, fragment, "stream_frag").commit(); 
    }   
私はOnCreateのかのgetURLの内側に初期化する必要があります
+0

ありがとう、私はあなたがインターフェイスを作成する代わりに言ったことを達成することができた新しい活動..あなたは私にいくつかの記憶を救った:)私は十分なポイントを持っていないか、あなたに投票しただろう –

+0

喜んで助けてください。 Androidには約1 1/2年しかないが、まだ自分自身で多くのことを学んでいる。もしあなたが最後の質問であなたに戻ってくることがないなら、私に助言しようとします。 – Gary99

+0

あなたも私を助けることができる..質問はまだ答えられていない!私はターゲットの断片にデータを送信することができません:( –

関連する問題