android - Fragment.replace 不会删除一个 fragment ,而是与多个其他 fragment 一起使用

标签 android listview android-fragments

编辑: 以下问题出现在我的 Samsung Galaxy S3 上,但是,当我在我的 Sony Xperia Z3+ 上运行相同的应用程序时,它根本不显示 WIFI 列表。 :-/

我的应用出现了奇怪的情况。我目前有五个不同的 fragment 。所有这些都按预期工作 FragmentTransaction除了一个。
最初,当我启动我的应用程序时,我使用了一个 Android Studio 模板,但这似乎太过分了,因为它使用了 Fragments。而不是 ListView用于列出我的 WIFI 项目。我已经有一段时间没有使用 Android 开发任何东西了,所以我正在努力追赶。

我将代码留在原地并继续开发界面。当我最终决定删除用 Fragment 填充主容器的代码时,问题就来了。 “项目”并将其替换为 Fragment包含 ListView .

我所有的Fragments当我从菜单中选择新项目时按预期工作并按预期替换,但这个新的 ListView Fragment 除外。 ,一旦我选择它,它就会保留在后台。

我选择之后,如果我选择其他Fragments它们按应有的方式更改,但第一个保留在原位。

我发现最接近我的情况的问题是 this one ,但这对我没有帮助。

这是选择问题后我的屏幕的样子 Fragment和另一个 Fragment :

Layered Fragments

我的 MainActivity onCreate()方法:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        setupWifiScan();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Scanning for devices...", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
                scanForNetworks(view);
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        if(findViewById(R.id.fragment_container) != null){

            if(savedInstanceState != null){
                return;
            }

            NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
            navigationView.setNavigationItemSelectedListener(this);

            WifiFragment wifiFragment = new WifiFragment();
            wifiFragment.setArguments(getIntent().getExtras());
            FragmentManager manager = getSupportFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.fragment_container, wifiFragment);
            transaction.commit();
        }else{
            Log.i("MAIN_ACTIVITY", "fragment_container is NULL");
        }
    }

我的 MainActivity onNavigationItemSelected()方法:

@覆盖 公共(public) bool onNavigationItemSelected(菜单项){ //处理导航 View 项点击这里。 int id = item.getItemId();

if (id == R.id.nav_settings) {

    GeneralSettings generalSettings = new GeneralSettings();
    Bundle args = new Bundle();
    args.putInt(GeneralSettings.ARG_POSITON, 0);
    generalSettings.setArguments(args);

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.fragment_container, generalSettings);
    transaction.addToBackStack(null);
    int stackId = transaction.commit();
    Log.i(this.getClass().getSimpleName(), "Stack ID: " + stackId);

}else if(id == R.id.nav_wlan_setting){

    WifiSettings wifiSettings = new WifiSettings();
    Bundle args = new Bundle();
    args.putInt(GeneralSettings.ARG_POSITON, 0);
    wifiSettings.setArguments(args);

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.fragment_container, wifiSettings);

    transaction.addToBackStack(null);
    int stackId = transaction.commit();
    Log.i(this.getClass().getSimpleName(), "Stack ID: " + stackId);

}else if(id == R.id.nav_led_settings){

    UvLedSettings uvLedSettings = new UvLedSettings();
    Bundle args = new Bundle();
    args.putInt(GeneralSettings.ARG_POSITON,0);
    uvLedSettings.setArguments(args);

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.fragment_container, uvLedSettings);
    transaction.addToBackStack(null);
    int stackId = transaction.commit();
    Log.i(this.getClass().getSimpleName(), "Stack ID: " + stackId);

}else if(id == R.id.nav_server_settings){

    ServerSettings serverSettings = new ServerSettings();
    Bundle args = new Bundle();
    // TODO: Fix Args Settings for all Fragments
    args.putInt(GeneralSettings.ARG_POSITON, 0);
    serverSettings.setArguments(args);

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.fragment_container, serverSettings);

    transaction.addToBackStack(null);
    int stackId = transaction.commit();
    Log.i(this.getClass().getSimpleName(), "Stack ID: " + stackId);

} else if (id == R.id.nav_current_device) {

} else if (id == R.id.nav_available_devices){

    WifiFragment wifi = new WifiFragment();
    Bundle args = new Bundle();
    args.putInt(GeneralSettings.ARG_POSITON, 0);
    wifi.setArguments(args);

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.fragment_container, wifi);
    transaction.addToBackStack(null);
    int stackId = transaction.commit();
    Log.i(this.getClass().getSimpleName(), "Stack ID: " + stackId);

}

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
    return true;
}

问题Fragment :

package com.myapp.serviceapplication.fragments;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.RelativeLayout;


import com.myapp.serviceapplication.R;
import com.myapp.serviceapplication.adapters.WifiItemListAdapter;

import java.util.ArrayList;

/**
 * A fragment representing a list of Items.
 * <p>
 * Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener}
 * interface.
 */
public class WifiFragment extends Fragment {

    // TODO: Customize parameter argument names
    private static final String ARG_COLUMN_COUNT = "column-count";
    // TODO: Customize parameters
    private int mColumnCount = 1;
    private OnListFragmentInteractionListener mListener;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public WifiFragment() {
        // Required empty public constructor
    }

    // TODO: Customize parameter initialization
    @SuppressWarnings("unused")
    public static WifiFragment newInstance(int columnCount) {
        WifiFragment fragment = new WifiFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_COLUMN_COUNT, columnCount);
        fragment.setArguments(args);
        return fragment;
    }

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

        if (getArguments() != null) {
            mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
        }

    }

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

        if(view instanceof RelativeLayout){
            Context context = view.getContext();
            RelativeLayout relativeLayout = (RelativeLayout) view;
            ListView listView = (ListView) relativeLayout.findViewById(R.id.lst_wifi_items);
            listView.setAdapter(new WifiItemListAdapter(this.getContext(), new ArrayList<ScanResult>()));
        }
        return view;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        // TODO: This needs to be modified to the correct listener type
        if (context instanceof OnListFragmentInteractionListener) {
            mListener = (OnListFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnListFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnListFragmentInteractionListener {
        // TODO: Update argument type and name
        void onListFragmentInteraction(View item);
    }
}

问题Fragment布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragments.WifiFragment"
    >

<ListView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/lst_wifi_items"
    android:background="#ffffff"/>

</RelativeLayout>

content_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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".activities.MainActivity"
    tools:showIn="@layout/app_bar_main">


    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

我花了太多时间试图解决这个问题,但我就是看不到问题所在。

最佳答案

发生这种情况是因为您的 fragment 容器位于 ListView 之上,默认情况下,如果您不在 ViewGroup(LinearLayout, RelativeLayout,...) 中使用背景,那么它将是透明的,因此,您需要做的就是将背景放入你的 fragment 容器:

fragment_wifi_list.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragments.WifiFragment"

    android:background="#ffffff"

    >
    ...

提示:

android:clickable="true"

这样就避免了并发点击问题

关于android - Fragment.replace 不会删除一个 fragment ,而是与多个其他 fragment 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38457844/

相关文章:

android - TextInputLayout 以编程方式设置 startIconDrawable 的颜色

java - ListItem 不响应 Android ArrayAdapter 中的 clickEvents?

android - FragmentTabHost - 选项卡在第一次查看之前不可寻址

Android ActionBar 选项卡 - 滑动

安卓 : Save fragment state and restore the view values

android - 蓝牙 LE 限制 Play 商店的可用性

android - 如何使图像适合 Android 中的自定义 256dp 大图片通知?

android - Firebase 查询 limitToLast 无法按预期工作

c# - Listview ItemSelectionChanged,如何取消/撤消

java - SearchView 显示错误的 ListView 项目