2016-10-15 5 views
2

Ich habe ein Fragment (fragment_address), das in einem Fragment-Container in meiner Hauptaktivität angezeigt wird. Mein fragment_address Fragment zeigt eine Liste gepaarter Geräte an. Wenn auf ein aufgelistetes Objekt geklickt wird, wird das Fragment in meiner Hauptaktivität durch ein anderes Fragment ersetzt. Dieses Fragment hat Knöpfe, um andere Fragmente hervorzubringen. Das alles funktioniert gut, bis ich auf eine Schaltfläche klicke, um ein neues Fragment zu öffnen und die fragment_address im Hintergrund sowie mein neues Fragment angezeigt wird. Da das Adressfragment nur einmal benötigt wird, gibt es eine Möglichkeit sicherzustellen, dass dieses Fragment beim Ersetzen zerstört wird?Zerstöre ein Fragment beim Ersetzen

Meine Hauptaktivität.

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(); 
    } 
} 

Die 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> 

Meine Adresse Fragment

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); 
      } 
     } 
    } 
} 

Meine Adresse 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> 

Und mein OnStart, die die MainFragment mit dem ControlOutputs Fragment ersetzt, wenn butControlOutputs genannt wird.

@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 

Ich habe die addToBackStack in und entfernt es wieder. Ich dachte, das ft.replace würde das vorherige Fragment zerstören, wenn das vorherige nicht zum Backstack hinzugefügt wurde ??

Ich habe dies dem OnClickListener hinzugefügt. Es fügt das MainFragment hinzu, gibt aber immer 'Null' für das AddressFragment zurück.

Antwort

1

Wenn Sie diese Fragmente nicht manuell entfernen, werden sie weiterhin an die Aktivität angehängt. Deine Aktivität wird nicht zerstört, also sind diese Fragmente auch. Um diese Fragmente zu entfernen (also zu zerstören), können Sie anrufen:

Sie müssen findFragmentById für Fragment aus XML-Datei verwenden.

nennen dies auf MainActivity

Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_frag) 

Und das auf OnClick Listener Methode

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

Ich habe auf diese ähnlich gesehen, aber kann sie nicht arbeiten. Wie füge ich einen TAG hinzu, wenn die MainActivity das Fragment – fatmanming

+0

startet und dann in der MainActivity auf click listener findet. – fatmanming

+0

Mein ursprüngliches Adressfragment wird nicht dynamisch hinzugefügt. Es wurde von der XML.class = "com.ming.pondcontroller.AddressFragment" android: id = "@ + id/main_frag" – fatmanming

Verwandte Themen