1

Эти фрагменты являются частью нижней навигационной панели, настолько удачной в навигационной части. Но когда я пытаюсь передать данные от фрагмента1 к фрагменту2, приложение рушится. Также я использую пример, приведенный google, следующим образом: linkКоммуникация между фрагментами через интерфейсы

Когда я использую следующий код, студия Android предлагает мне устаревшее предупреждение!

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

Так я использую КОНТЕКСТ вместо АКТИВНОСТЬ ниже мой код, который выходит из строя:

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, где я хочу, чтобы отправить -из данных 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: FATAL EXCEPTION: main Процесс: com.br.tron.bottombar, PID: 3744 java.lang.NullPointerException: попытка вызвать виртуальный метод 'void com.br.tron.bottombar.StreamFragment.getUrl (java.lang.String)' на нулевой ссылке объекта на com.br.tron.bottombar.MainActivity.setUrl (MainActivity.java:64) на com.br.tron.bottombar.RadioFragment.onClick (RadioFragment.java:61) на 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) at 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

Вы должны инициализировать textViewStream в StreamFragment фрагменте.

+0

Где я должен инициализировать OnCreate или внутри GetURL? что лучше ? –

+0

Пожалуйста, добавьте дополнительную информацию к вам. Возможно, объясните, почему это решение должно работать и почему путь OP не работает. –

3

Вы никогда не регистрируете тег frag, который вы позже можете найти.

В вашем MainActivity изменения:

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(); 
... 

В дополнение к этому в своем классе StreamFragment вы никогда не установить переменную TextViewStream после надувания макета.

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

Edit: Другие ошибки

Вы получаете ClassCastException, потому что вы не проверяет, является ли фрагмент вы получаете в MainActivity.setUrl является StreamFragment. И имеет смысл, что он терпит неудачу, потому что вы регистрируете тег 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

все еще сбой mate Я инициализировал textViewStream, поскольку siva уже указал это и изменил MainActivity в соответствии с вашим предложением –

+0

@ user3599100 Является ли stacktrace тем же самым? Не могли бы вы разместить новую стек. – asadmshah

+0

Новый Stack след -> java.lang.ClassCastException: RadioFragment не может быть приведен к StreamFragment Ориентировочно этот код указывает на -> '@Override общественного недействительными setUrl (String URL) { StreamFragment осколочная = (StreamFragment) getSupportFragmentManager() .findFragmentByTag ("фраг"); 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() в том же порядке, что и раньше, вы получаете нуль, потому что вы никогда не создавали фрагмент с этим именем. Вы не можете найти фрагмент, который вы еще не создали.

Не устанавливая это, чтобы проверить его самостоятельно, я считаю, что вам нужно сохранить URL-адрес в глобальной переменной в setUrl(), а затем в своем прослушивателе кликов передать это StreamFragment при его создании.

Смотрите «Доставить сообщение для фрагмента» части ссылки вы делаете для образом расположенной, что

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

(очевидно, обработка вашей строки 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(); 
    }   
+0

Спасибо человеку, что я смог достичь того, что вы сказали через интерфейс, вместо создания новая деятельность .. вы сохранили мне некоторую память :) У меня недостаточно очков или вы бы проголосовали за вас –

+0

Рад помочь. Только около 1 1/2 года в Android и все еще многому учусь. Если Асад не вернется к вам в последний вопрос, дайте мне знать, и я постараюсь помочь. – Gary99

+0

вы тоже могли бы мне помочь .. вопрос по-прежнему остается без ответа! Я не могу отправить данные в целевой фрагмент :( –