我有一个片段(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();
答案 0 :(得分:2)
如果您不手动删除这些片段,它们仍会附加到活动中。你的活动没有被破坏所以这些碎片也是如此。要删除(破坏)这些片段,您可以调用:
您需要从XML文件中使用findFragmentById for Fragment。
在 MainActivity
上调用此方法Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_frag)
这是 OnClick侦听器方法
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();