【问题标题】:TextView in Fragment will not updateFragment中的TextView不会更新
【发布时间】:2018-12-14 15:36:08
【问题描述】:

我在试图从 MainActivity 更新的片段中有一个 TextView。 我正在使用接口与 MainActivity 进行通信,而 MainActivity 正在调用片段中的公共方法。

我使用 onCreateView() 和 onActivityCreate() 来获取 TextView,但两者都给出了相同的结果。当我调试应用程序时,片段中 updateFact() 方法的 newFact 变量是从 MainActivity 设置的,但 TextView 不会改变。

片段不是 MainActivity 的一部分,并且正在通过 Activities onCreate() 方法加载到 Activity 的 FrameLayout 中。

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

事实片段

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();//-->
}

【问题讨论】:

    标签: android android-fragments android-inflate


    【解决方案1】:

    你在这里犯错了

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

    您应该在replace 中使用factFragment 而不是new FactFragment()

    以下是使用 fragmentManager 的更新代码,您可以使用它来修复此问题。

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

    【讨论】:

      【解决方案2】:

      您使用了错误的方法在活动与片段之间进行通信。您无法通过公共方法安全地与 Fragment 进行通信。

      而是:

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

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多