片段中的TextView无法更新

时间:2018-12-14 15:36:08

标签: android android-fragments android-inflate

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

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

该片段不是MainActivity的一部分,而是通过Activity onCreate()方法加载到活动的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();
    }
}

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 :(得分:0)

您在这里犯错了

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

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

下面是使用fragmentManager的更新代码,您可以用来解决此问题。

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

答案 1 :(得分:0)

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

相反:

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

}