更换后销毁碎片

时间:2016-10-15 16:39:05

标签: android android-fragments

我有一个片段(fragment_address)显示在我的主要活动的Fragment容器中。我的fragment_address片段会显示已配对设备的列表。单击列出的项目时,片段将在我的主活动中被另一个片段替换。 这个片段有按钮来显示其他片段。 这一切都正常,直到我单击一个按钮以显示一个新的片段,并在后台和我的新片段中显示fragment_address。 由于地址片段只需要一次,有没有办法确保这个片段在被替换时被销毁?

我的主要活动。

import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity implements AddressFragment.OnAddressListener {
    private static final String TAG = "Main Activity";
    // MAC-address of Bluetooth module (you must edit this line)
    private static String address = "No Device Selected";
    private static String deviceName = "No Device Selected";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onAddressChanged(String itemAddress, String itemName){
        // Set your address
        address = itemAddress;
        deviceName = itemName;
        MainFragment fragMain = new MainFragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        fragMain.setVariables(address, deviceName);
        ft.replace(R.id.main_frag, fragMain);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.commit();
    }
}

xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        class="com.ming.pondcontroller.AddressFragment"
        android:id="@+id/main_frag"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

我的地址片段

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.Set;

public class AddressFragment extends Fragment {

    private static final String TAG = "Address Activity";
    private BluetoothAdapter BA = null;
    private Set<BluetoothDevice> pairedDevices;
    LayoutInflater inflater2;
    ListView lv;
    String address;
    String itemName;
    String itemString;
    OnAddressListener mListener;

    public AddressFragment() {
        // Required empty public constructor
    }

    // Container Activity must implement this interface
    public interface OnAddressListener {
        public void onAddressChanged(String address, String itemName);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        inflater2 = inflater;
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_address, container, false);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnAddressListener ) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnAddressListener");
        }
    }

    @Override
    public void onStart(){
        super.onStart();
        lv = (ListView)getView().findViewById(R.id.listView);
        BA = BluetoothAdapter.getDefaultAdapter();
        checkBTState();

        // get paired devices
        pairedDevices = BA.getBondedDevices();
        ArrayList list = new ArrayList();
        // get a list of paired devices
        for(BluetoothDevice bt:pairedDevices){
            list.add(bt.getName()+"\n"+bt.getAddress());
        }
        // display the list in the list view
        final ArrayAdapter adapter = new ArrayAdapter(inflater2.getContext(),android.R.layout.simple_list_item_1,list);
        lv.setAdapter(adapter);

        // onItemClick Listener
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> adapterView,View view, int position, long l){
                // get the text of the item clicked from position
                itemString = (String)(lv.getItemAtPosition(position));
                // get last 17 characters for MAC address
                address = itemString.substring(itemString.length()-17);
                itemName = itemString.substring(0,itemString.length()-17);
                // send strings back to main Activity
                mListener.onAddressChanged(address,itemName);
            }
        }); //end of onClickListener
    }

    private void checkBTState() {
        // Check for Bluetooth support and then check to make sure it is turned on
        // Emulator doesn't support Bluetooth and will return null
        if(BA==null) {
            Log.d("Fatal Error", "Bluetooth not support");
        } else {
            if (BA.isEnabled()) {
                Log.d(TAG, "...Bluetooth ON...");
            } else {
                //Prompt user to turn on Bluetooth
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, 1);
            }
        }
    }
}

我的地址Fragment 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"
    android:background="@color/colorMainBack"
    tools:context="com.ming.pondcontroller.AddressFragment">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:id="@+id/textView"
        android:background="@color/colorPrimary"
        android:textColor="@color/colorWhite"
        android:textSize="20dp"
        android:text="Select Device"/>
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/textView"
        android:background="@color/colorTextBack">
    </ListView> />
</RelativeLayout>

当调用butControlOutputs时,我的OnStart正在用ControlOutputs Fragment替换MainFragment。

@Override
public void onStart() {
    super.onStart();
    TextView tv = (TextView)getView().findViewById(R.id.textIn);
    tv.setText(address);
    TextView tv2 = (TextView)getView().findViewById(R.id.textIn2);
    tv2.setText(deviceName);
    // Get ID's of buttons
    Button butSyncData = (Button)getActivity().findViewById(R.id.butSyncData);
    Button butControlOutputs = (Button)getActivity().findViewById(R.id.butControlOuts);
    Button butDateTime = (Button)getActivity().findViewById(R.id.butDateTime);
    Button butPreferences = (Button)getActivity().findViewById(R.id.butPreferences);
    Button butFullData = (Button)getActivity().findViewById(R.id.butFullData);
    // Create OnClick listener for each button
    butSyncData.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Log.d(TAG,"Button Get Now data Clicked");
            if(ConStatus == true){
                mConnectedThread.write(MainFragment.getNowData); // Sync Data to start
            }else if(!(address == "No Device Selected")) {
                btAdapter = BluetoothAdapter.getDefaultAdapter();       // get Bluetooth adapter
                BluetoothDevice device = btAdapter.getRemoteDevice(address);

                ConnectThread ct = new ConnectThread(device);
                ct.start();
            }
        }
    });

    butControlOutputs.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Log.d(TAG,"Control Outputs Clicked");
            // TODO rest of Control Outputs Launch
            OutputsFragment fragOutputs = new OutputsFragment();
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.main_frag,fragOutputs);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            ft.commit();
        }
    });

    butDateTime.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Log.d(TAG,"Date & Time Clicked");
            Toast.makeText(getActivity(),"Date & Time Clicked",Toast.LENGTH_SHORT).show();
            // TODO rest of Date Time Launch
        }
    });

    butPreferences.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Log.d(TAG,"Preferences Clicked");
            Toast.makeText(getActivity(),"Preferences Clicked",Toast.LENGTH_SHORT).show();
            // TODO rest of Control Outputs Launch
        }
    });

    butFullData.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Log.d(TAG,"Full Data Clicked");
            Toast.makeText(getActivity(),"Full Data Clicked",Toast.LENGTH_SHORT).show();
            // TODO rest of Control Outputs Launch
        }
    });

    // Start thread to connect to bluetooth
    if(!(address == "No Device Selected")) {
        btAdapter = BluetoothAdapter.getDefaultAdapter();       // get Bluetooth adapter
        BluetoothDevice device = btAdapter.getRemoteDevice(address);

        ConnectThread ct = new ConnectThread(device);
        ct.start();
    }
} // End of on start

我已经使用addToBackStack并再次将其删除。我认为ft.replace会破坏之前的片段,如果之前的片段没有被添加到后栈?

我已将此添加到OnClickListener中。它添加了MainFragment,但始终为AddressFragment返回'null'。

Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_frag);
        if(fragment != null) {
            Log.d("In OAC","Fragment Not NULL");
            getSupportFragmentManager().beginTransaction().remove(fragment).commit();
        }else{
            Log.d("In OAC","Fragment NULL");
        }
        MainFragment fragMain = new MainFragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        fragMain.setVariables(address, deviceName);
        ft.add(R.id.main_frag, fragMain);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.commit();

1 个答案:

答案 0 :(得分:2)

如果您不手动删除这些片段,它们仍会附加到活动中。你的活动没有被破坏所以这些碎片也是如此。要删除(破坏)这些片段,您可以调用:

您需要从XML文件中使用findFragmentById for Fragment。

MainActivity

上调用此方法
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_frag)

这是 OnClick侦听器方法

 if(fragment != null)
        getSupportFragmentManager().beginTransaction().remove(fragment).commit();