TextView во фрагменте не будет обновляться - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть TextView во фрагменте, который я пытаюсь обновить из MainActivity.Я использую интерфейс для связи с MainActivity, а MainActivity вызывает публичный метод во фрагменте.

Я использовал onCreateView () и onActivityCreate (), чтобы получить TextView, но оба дали один и тот же результат.Когда я отлаживаю приложение, переменная newFact метода updateFact () во фрагменте устанавливается из MainActivity, но TextView не изменяется.

Фрагмент не является частью MainActivity и загружается в FrameLayout действия в методе Activity onCreate ().

MainActivity

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
    FragmentContract{

Toolbar mToolbar;
DrawerLayout mDrawerLayout;
private FactFragment factFragment;
private RandomFragment randomFragment;

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

    //show FactFragment when app is opened
   getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
            new FactFragment()).commit();

}//onCreate()




//overriden methods of FragmentContract
@Override
public void randomSwipe() {

}

@Override
public void leftToRight() {
    if(factFragment != null){
        Toast.makeText(this,"left to right in main",Toast.LENGTH_SHORT).show();
        factFragment.updateFact("from main");
        //factFragment.getActivity().findViewById(R.id.factFragTV);
    }else {
        Toast.makeText(this, "fragment is null", Toast.LENGTH_SHORT).show();
    }
}

FactFragment

public class FactFragment extends Fragment {
    //communicate between fragment and activity
    private FragmentContract communicator;
    private TextView fact;


    public FactFragment(){}


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        //assign listener variable (communicator) and check if
        //MainActivity implements the interface
        if(activity instanceof FragmentContract){
            //assign listener variable
            communicator = (FragmentContract) activity;
            Log.d("tag", "listener assigned");
        }else{
            throw new RuntimeException(activity.toString() + "must implement FragmentContract");
        }
    }


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        //this method is used to instantiate the views
        View rootView = inflater.inflate(R.layout.fragment_fact, container, false);
        factBackground = (ImageView) rootView.findViewById(R.id.factImageFrag);
        fact = (TextView) rootView.findViewById(R.id.factFragTV);


        //listen for swipe gestures
        final GestureDetector gesture = new GestureDetector(getActivity(),
                new GestureDetector.SimpleOnGestureListener() {

                    @Override
                    public boolean onDown(MotionEvent e) {
                        return true;
                    }

                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

                        final int SWIPE_MIN_DISTANCE = 120;
                        final int SWIPE_MAX_OFF_PATH = 250;
                        final int SWIPE_THRESHOLD_VELOCITY = 200;
                        try {
                            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                                return false;
                            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                                //Toast.makeText(getActivity(), "left To right", Toast.LENGTH_SHORT).show();
                                communicator.leftToRight();
                            }
                        } catch (Exception e) {
                            // nothing
                        }
                        return super.onFling(e1, e2, velocityX, velocityY);
                    }
                });

        rootView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gesture.onTouchEvent(event);
            }
        });

        return rootView;
    }//onCreateView()


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        fact = (TextView) getActivity().findViewById(R.id.factFragTV);
    }

    public void updateFact(String newFact){
        fact.setText(newFact);
        Toast.makeText(getActivity(), "updateFact called in fragment", Toast.LENGTH_SHORT).show();
        Log.d("tag","Update()" + newFact);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        communicator = null;
    }
}//FactFragment

Интерфейс

    public interface FragmentContract {

    void randomSwipe();

    void leftToRight();//-->
}

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Вы используете неправильный подход для связи между деятельностью к фрагменту.Вы не можете безопасно общаться с фрагментом через открытый метод.

Скорее:

1.Сделайте другой интерфейс только с одним методом с именем void updateFact(String newFact)

public interface Listener {

    void updateFact(String newFact);

}

2. Внедрите интерфейс в Fragment и переопределите метод

public class FactFragment extends Fragment implements Listener{
.
.
@Override
    public void updateFact(String newFact){
      fact.setText(newFact);
      Toast.makeText(getActivity(), "updateFact called in fragment", Toast.LENGTH_SHORT).show();
      Log.d("tag","Update()" + newFact);
    }


}

3. Создайте глобальную переменную интерфейса и введите объект Fragment в переменную интерфейса.4. При необходимости общайтесь через слушателя.

 public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, FragmentContract{

private Listener listener;
.
.
@Override
protected void onCreate(Bundle savedInstanceState) {
.
.
.
factFragment = new FactFragment();
listener = (Listener) factFragment; 

getSupportFragmentManager(). beginTransaction().replace(R.id.fragment_container,
        factFragment).commit();

} 
@Override
public void leftToRight() {
if(listener != null){
    Toast.makeText(this,"left to right in main",Toast.LENGTH_SHORT).show();
    listener.updateFact("from main");
}else {
    Toast.makeText(this, "fragment is null", Toast.LENGTH_SHORT).show();
}

}

0 голосов
/ 14 декабря 2018

Вы делаете ошибку здесь

getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
            new FactFragment()).commit();

Вы должны использовать factFragment вместо new FactFragment() в replace.

Ниже приведен обновленный код использования фрагмента управления, который вы можетеиспользовать для решения этой проблемы.

 getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                factFragment).commit();
...