我正在尝试从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();//-->
}
答案 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();
}
}