【问题标题】:Replace fragmentA with fragmentB issue用片段问题替换片段
【发布时间】:2017-10-15 17:26:44
【问题描述】:

我在主要活动中有一个图像,当单击此图像时,我想显示具有列表视图的片段 A。

当单击此 listView 的一个项目时,我想用具有 textview 的 fragmentB 替换 fragmentA,并且我想在此 textview 中显示与单击的列表项关联的文本。

所以在主要活动我有这个:

public class MainActivity extends AppCompatActivity implements  Listener{
    private ImageView img;
    private String text;
    FragmentManager fragmentManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragmentManager = getFragmentManager();
        img = (ImageView) findViewById(R.id.imageView);
    }
    public void AddFragmentA(View view) {
        FragmentA fragmentA = new FragmentA();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.containerFragmentA, new FragmentA(), "fragA");
        transaction.commit();
    }
    public void AddFragmentB() {
        FragmentB fragment = new FragmentB();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
        transaction.commit();
    }
    @Override
    public void addText(String text) {
        this.text = text;
        Toast.makeText(this, "Text received in Activity:" +text, Toast.LENGTH_SHORT).show();
        sendDataToFragmentB();
    }

 public void sendDataToFragmentB(){

            FragmentB fragmentB = (FragmentB) fragmentManager.findFragmentByTag("fragB");
            fragmentB.addText(text);
        }
}

注意:此时 addText() 中的 toast 出现了正确的文本,因此在 Activity 中成功接收到列表视图的文本。

问题:现在如何用fragmentB替换fragmentA,并在activity中用接收到的文本显示textview,而不是显示fragmentA的listview?

下面是完整的例子。

FragmentA 类:

public class FragmentA extends Fragment{
    private ListView listItems;
    private String[] items = {
            "item1",
            "item2",
            "item3",
            "item4"
    };
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
        return view;
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        listItems = (ListView) getView().findViewById(R.id.listviewInFragment);

        ArrayAdapter<String> adapter =
                new ArrayAdapter<String>(getActivity().getApplicationContext(),
                        android.R.layout.simple_list_item_1, android.R.id.text1, items);

        listItems.setAdapter(adapter);
        listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                int positionCode = i;

                String clickedValue = (String) adapterView.getItemAtPosition(i);
                Listener listener = (Listener) getActivity();
                listener.addText(clickedValue);
            }
        });
    }

}

FramentB:

public class FragmentB extends Fragment {
    private TextView tv;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b, container, false);
        tv = (TextView) getView().findViewById(R.id.textView);
        return view;
    }
    public void addText(String text) {
        String result = text;
        tv.setText(result);
    }
}

主要活动 xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/image"
        android:onClick="AddFragmentA"
        tools:layout_editor_absoluteX="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp" />
    <FrameLayout
        android:id="@+id/containerFragmentA"
        android:layout_width="0dp"
        android:layout_height="300dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        tools:layout_editor_absoluteY="1dp">
    </FrameLayout>

    <FrameLayout
        android:id="@+id/containerFragmentB"
        android:layout_width="0dp"
        android:layout_height="300dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        tools:layout_editor_absoluteY="1dp">
    </FrameLayout>
</android.support.constraint.ConstraintLayout>

对 xml 进行分段:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0ff">

    <ListView
        android:layout_width="368dp"
        android:layout_height="495dp"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="16dp"
        android:id="@+id/listviewInFragment"/>

</android.support.constraint.ConstraintLayout>

片段 b xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff0">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="300dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
         />
</android.support.constraint.ConstraintLayout>

【问题讨论】:

  • 检查我的答案here,您可以使用带有两个片段的 ViewPager,通过触摸限制滚动,只需在 ListView 的项目单击上使用提供的解决方案。横向滚动会给你的 UI 一个很好的效果,而不是替换

标签: android android-fragments


【解决方案1】:

这就是您完成所需任务的方式。 在下面对您的班级进行相应的更改。 MainActivity.java

public class MainActivity extends AppCompatActivity implements FragmentA.ClickListener{
    private Button button;
    public static String EXTRA_STRING = "extraString";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AddFragment(FragmentA.getInstance());
            }
        });
    }
    public void AddFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.containerFragmentA, fragment).commit();
    }

    @Override
    public void onClick(String data) {
        AddFragment(FragmentB.getInstance(data));
    }
} 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/containerFragmentA"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_editor_absoluteY="1dp"/>

    <Button
        android:id="@+id/button"
        style="@style/Widget.AppCompat.Button.Colored"
        android:layout_margin="8dp"
        android:layout_alignParentBottom="true"
        android:text="Add Fragment B"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

FragmentA.java

public class FragmentA extends Fragment {
private ListView listItems;
private String[] items = {"item1", "item2", "item3", "item4"};
private ClickListener clickListener;

public static FragmentA getInstance() {
    return new FragmentA();
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    clickListener = (ClickListener)context;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_a, container, false);
    return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    listItems = (ListView) getView().findViewById(R.id.listviewInFragment);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1, items);
    listItems.setAdapter(adapter);
    listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            String clickedValue = items[i];
            clickListener.onClick(clickedValue);
        }
    });
}

public interface ClickListener{
    void onClick(String data);
}

}

fragment_a.xml

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="368dp"
        android:layout_height="495dp"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="16dp"
        android:id="@+id/listviewInFragment"/>

</android.support.constraint.ConstraintLayout>

FragmentB.java

public class FragmentB extends Fragment {
    private TextView tv;
    private String data;

    public static FragmentB getInstance(String data){
        Bundle bundle = new Bundle();
        bundle.putString(MainActivity.EXTRA_STRING,data);
        FragmentB fragmentB = new FragmentB();
        fragmentB.setArguments(bundle);
        return fragmentB;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b, container, false);
        tv = view.findViewById(R.id.textView);
        data = getArguments().getString(MainActivity.EXTRA_STRING);
        addText(data);
        return view;
    }
    public void addText(String text) {
        String result = text;
        tv.setText(result);
    }
}

fragment_b.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:gravity="center"
        android:textSize="24dp"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.PopupMenu.Header"
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

【讨论】:

    【解决方案2】:

    您将片段 A 放在下面的函数中,而不是片段 B

     public void AddFragmentB() {
            FragmentB fragment = new FragmentB();
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
            transaction.commit();
        }
    

    应该是

    public void AddFragmentB() {
            FragmentB fragment = new FragmentB();
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.containerFragmentB, new FragmentB(), "fragB");
            transaction.commit();
        }
    

    如果您想用另一个片段替换片段,只需使用相同的容器 不要创建单独的 (R.id.containerFragmentB, R.id.containerFragmentA) 容器。

    【讨论】:

    • 谢谢。但是现在当我单击列表项时,它会显示“应用程序不断停止”。这似乎是因为我将在问题中更新的 sendDataToFragmentB 方法。
    • 一分钟后给你发回消息。
    • 添加了另一个答案,请查看。适合我
    【解决方案3】:

    你需要改变你的

     public void AddFragmentA(View view) {
        FragmentA fragmentA = new FragmentA();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.containerFragmentA, new FragmentA(), "fragA");
        transaction.commit();
    }
    public void AddFragmentB() {
        FragmentB fragment = new FragmentB();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
        transaction.commit();
    }
    

     public void AddFragmentA(View view) {
        FragmentA fragmentA = new FragmentA();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.container, fragmentA , "fragA");
        transaction.commit();
    }
    public void AddFragmentB() {
        FragmentB fragment = new FragmentB();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.container, fragment, "fragB");
        transaction.commit();
    }
    

    并且activity_main.xml应该是

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/image"
            android:onClick="AddFragmentList"
            tools:layout_editor_absoluteX="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginBottom="8dp" />
        <FrameLayout
            android:id="@+id/container"
            android:layout_width="0dp"
            android:layout_height="300dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            tools:layout_editor_absoluteY="1dp">
        </FrameLayout>
    
    
    </android.support.constraint.ConstraintLayout>
    

    编辑

     listItems.setAdapter(adapter);
        listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                int positionCode = i;
    
                String clickedValue = (String) adapterView.getItemAtPosition(i);
                Listener listener = (Listener) getActivity();
                listener.addText(clickedValue);
            }
        });
    

    听众

    public interface IScanner {
    
    void addText(String Text);
    
    }
    

    MainActivity

    public class MainActivity extends AppCompatActivity implements  Listener{
    private ImageView img;
    private String text;
    FragmentManager fragmentManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragmentManager = getFragmentManager();
        img = (ImageView) findViewById(R.id.imageView);
    }
    public void AddFragmentA(View view) {
        FragmentA fragmentA = new FragmentA();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.containerFragmentA, new FragmentA(), "fragA");
        transaction.commit();
    }
    
    @Override
    public void addText(String text) {
        this.text = text;
        Toast.makeText(this, "Text received in Activity:" +text, Toast.LENGTH_SHORT).show();
        sendDataToFragmentB(text);
    }
    
     public void sendDataToFragmentB(String clickedValue){
        Bundle b = new Bundle();
        b.putString("clickedValue", clickedValue);
    
        FragmentB fragment = new FragmentB();
        fragment.setArguments(b);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
        transaction.commit();
        }
     }
    

    片段B

    public class FragmentB extends Fragment {
    private TextView tv;
    
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b, container, false);
        tv = (TextView) getView().findViewById(R.id.textView);
        return view;
    }
    Bundle bundle = this.getArguments();
    if (bundle != null) {
            String text = bundle.getString("clickedValue", "");
    }
    }
    

    这会解决你的问题

    【讨论】:

    • 谢谢,但它也不起作用,当我单击列表项时,它会显示“应用程序不断停止”。我认为这是因为 AddFragmentB 或 sendDataToFragmentB 方法。你知道 AddFragmentB() 应该放在哪里吗?
    • @JonD 您的数据没有传递,因为您在提交片段时传递了一个新实例,您应该传递该对象
    • 我已经将 new FragmentB() 更改为片段,但问题仍然存在。我注意到我没有使用 AddFragmentB 函数,所以我将它添加到 onCreate 方法中,但我运行了应用程序并没有运行的应用程序这个方法 AddFragmentB 放在 onCreate 主活动方法上。
    • 等一下,我将对您的代码进行一些更改,可能对您有用,但需要一些时间
    • 谢谢,但它不起作用。您的示例中没有使用 AddFragmentB 方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多