2017-07-03 43 views
0

我的代碼中有兩個基本類:機場和航班(出發和到達)。機場由到達航班對象列表和出發航班對象列表組成。 在我的主要活動中,我擁有一個機場對象列表並在列表視圖中表示它們。通過觸摸列表視圖對象,我將啓動一個新的活動,以顯示該機場對象(ActivityArrivalFlights)的所有到達航班,其中我將機場對象作爲字段保存。在這個活動中,有一個將到達航班添加到同一個對象的功能。我還在列表視圖中顯示航班,並通過數組適配器添加航班。在其他活動中創建的對象在主要活動中不可見

問題是這樣的:當一個飛行對象被創建並添加到機場時,只要活動存在,它就在那裏。當ActivityArrivalFlights被銷燬並且焦點在主要活動上時,先前添加的飛行對象不在該機場中。

下面是兩個活動的代碼。任何人都可以告訴我,如果我做錯了什麼?

public class MainActivity extends AppCompatActivity { 

    private static final int FILL_AIRPORT_REQUEST = 1; 
    private static final int EDIT_AIRPORT_REQUEST = 2; 

    static final String EDIT_AIRPORT_OBJECT_KEY = "editable"; 
    static final String EDIT_AIRPORT_POSITION_KEY = "position"; 
    static final String SELECTED_AIRPORT_KEY = "selectedAirport"; 
    static final String ALL_FLIGHTS_LIST_KEY = "allFlights"; 

    private static final String AIRPORTS_STATE = "airportsState"; 

    private Button btnAddAirport; 
    private ListView lvAirports; 

    private ArrayList<Airport> airports; 
    private ArrayAdapter<Airport> airportArrayAdapter; 

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

     btnAddAirport = (Button) findViewById(R.id.btnAddAirport); 
     lvAirports = (ListView) findViewById(R.id.lwAirports); 
     btnAddAirport.setOnClickListener(this::onButtonAddAirportClick); 
     lvAirports.setOnItemClickListener(this::onListViewItemClicked); 


     if (savedInstanceState != null) 
      airports = savedInstanceState.getParcelableArrayList(AIRPORTS_STATE); 
     else 
      airports = new ArrayList<>(); 

     airportArrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, airports); 
     lvAirports.setAdapter(airportArrayAdapter); 
     lvAirports.invalidateViews(); 
     registerForContextMenu(lvAirports); 
     if(savedInstanceState == null) 
      addCodeForTesting(); 
    } 

    private void addCodeForTesting() { 
     /* TEMPORARY CODE FOR TESTING*/ 
     Airport munich = new Airport("MunichAirport", "Munich", "MU", 1234); 
     Airport skopje = new Airport("Aleksandar Veliki", "Skopje", "SK", 4321); 
     skopje.addArrivalFlight(munich, new Date(), new Date()); 
     airportArrayAdapter.add(skopje); 
     airportArrayAdapter.add(munich); 
    } 

    private void onButtonAddAirportClick(View view){ 
     startActivityForResult(new Intent(this, ActivityAddAirport.class), FILL_AIRPORT_REQUEST); 
    } 

    private void onListViewItemClicked(AdapterView parent, View view, int position, long id){ 
     Airport airport = airports.get(position); 
     showFlightsActivity(airport); 
    } 

    private void showFlightsActivity(Airport airport) { 
     Intent intent = new Intent(this, ActivityArrivalFlights.class); 
     ArrayList<Airport> filteredList = filterAirports(airports, airport); 
     intent.putExtra(SELECTED_AIRPORT_KEY, airport); 
     intent.putParcelableArrayListExtra(ALL_FLIGHTS_LIST_KEY, filteredList); 
     startActivity(intent); 
    } 

    private static ArrayList<Airport> filterAirports(List<Airport> original, Airport except){ 
     ArrayList<Airport> filtered = new ArrayList<>(); 
     for (Airport airport : original) { 
      if(!airport.equals(except)) 
       filtered.add(airport); 
     } 
     return filtered; 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
     if(requestCode == FILL_AIRPORT_REQUEST){ 
      if(resultCode == RESULT_OK){ 
       Airport airport = data.getParcelableExtra(ActivityAddAirport.AIRPORT_OBJECT_KEY); 
       airportArrayAdapter.add(airport); 
      } 
     } 
     else if(requestCode == EDIT_AIRPORT_REQUEST){ 
      if(resultCode == RESULT_OK){ 
       Airport editedAirport = data.getParcelableExtra(ActivityAddAirport.AIRPORT_OBJECT_KEY); 
       int airportPosition = data.getIntExtra(ActivityAddAirport.AIRPORT_POSITION, 0); 
       airports.remove(airportPosition); 
       airports.add(airportPosition, editedAirport); 
       airportArrayAdapter.notifyDataSetChanged(); 
       lvAirports.invalidateViews(); 
       Toast.makeText(this, "Airport changed", Toast.LENGTH_LONG).show(); 
      } 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putParcelableArrayList(AIRPORTS_STATE, airports); 
    } 

    @Override 
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { 
     super.onCreateContextMenu(menu, v, menuInfo); 
     getMenuInflater().inflate(R.menu.main_menu_context_menu, menu); 
    } 

    @Override 
    public boolean onContextItemSelected(MenuItem item) { 
     if(item.getItemId() == R.id.context_edit) { 
      AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); 
      editListViewItem(info.position); 
      return true; 
     } 
     else if (item.getItemId() == R.id.context_delete){ 
      AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); 
      deleteListViewItem(info.position); 
      return true; 
     } 
     return super.onContextItemSelected(item); 
    } 

    private void editListViewItem(int position) { 
     Intent editIntent = new Intent(this, ActivityAddAirport.class); 
     Airport changingAirport = (Airport) lvAirports.getItemAtPosition(position); 
     editIntent.putExtra(EDIT_AIRPORT_OBJECT_KEY, changingAirport); 
     editIntent.putExtra(EDIT_AIRPORT_POSITION_KEY, position); 
     startActivityForResult(editIntent, EDIT_AIRPORT_REQUEST); 
    } 

    private void deleteListViewItem(int position){ 
     airportArrayAdapter.remove(airports.get(position)); 
    } 
} 

public class ActivityArrivalFlights extends AppCompatActivity { 

    private static final int FILL_ARRIVAL_FLIGHT_REQUEST = 1; 

    static final String AIRPORT_THIS_KEY = "thisAirport"; 
    static final String ALL_AIRPORTS_EXCEPT_THIS_KEY = "allExceptThis"; 

    private Airport airport; 
    private ArrayList<Airport> allAirportsExceptThis; 

    private ArrayAdapter<ArrivalFlight> lvArrivalsAdapter; 


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

     FloatingActionButton fabAddArrival = (FloatingActionButton) findViewById(R.id.fabAddArrival); 
     fabAddArrival.setOnClickListener(this::onFabAddArrivalClick); 

     Intent intent = getIntent(); 
     airport = intent.getParcelableExtra(MainActivity.SELECTED_AIRPORT_KEY); 
     allAirportsExceptThis = intent.getParcelableArrayListExtra(MainActivity.ALL_FLIGHTS_LIST_KEY); 

     setUpListView(); 
    } 

    private void setUpListView(){ 
     ListView lvArrivals = (ListView) findViewById(R.id.lvArrivals); 
     lvArrivalsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, airport.getArrivals()); 
     lvArrivals.setAdapter(lvArrivalsAdapter); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu_choose_flights, menu); 
     return super.onCreateOptionsMenu(menu); 
    } 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
     MenuItem arrivals = menu.findItem(R.id.arrivals); 
     MenuItem departures = menu.findItem(R.id.departures); 
     if (arrivals.isEnabled()) 
      arrivals.setEnabled(false); 
     if (!departures.isEnabled()) 
      departures.setEnabled(true); 
     return super.onPrepareOptionsMenu(menu); 
    } 



    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     if(item.getItemId() == R.id.departures){ 
      Intent intent = new Intent(this, ActivityDepartureFlights.class); 
      intent.putExtra(MainActivity.SELECTED_AIRPORT_KEY, airport); 
      startActivity(intent); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private void onFabAddArrivalClick(View view){ 
     Intent intent = new Intent(this, ActivityAddArrivalFlight.class); 
     intent.putExtra(AIRPORT_THIS_KEY, airport); 
     intent.putParcelableArrayListExtra(ALL_AIRPORTS_EXCEPT_THIS_KEY, allAirportsExceptThis); 
     startActivityForResult(intent, FILL_ARRIVAL_FLIGHT_REQUEST); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if(requestCode == FILL_ARRIVAL_FLIGHT_REQUEST){ 
      if(resultCode == RESULT_OK){ 
       ArrivalFlight flight = data.getParcelableExtra(ActivityAddArrivalFlight.FILLED_FLIGHT_ENTRY); 
       lvArrivalsAdapter.add(flight); 
       Toast.makeText(this, "Flight added!\n" + airport.getArrivals().size(), Toast.LENGTH_SHORT).show(); 
      } 
     } 
    } 
} 

回答

0

我看不出爲什麼在ActivityArrivalFlights的破壞在MainActivity將被新的航班進行更新。

不必返回任何結果MainActivity(從ActivityArrivalFlights) 爲了將數據恢復到MainActivity,你的情況恢復已添加你需要做的是這樣的飛行:

在MainActivity:

final int NEW_FLIGHT_RESULT = 5; // Just an identifier number/what ever you want; 

// Start ActivityArrivalFlights for result (which you are not doing): 

private void showFlightsActivity(Airport airport) { 
    Intent intent = new Intent(this, ActivityArrivalFlights.class); 
    ArrayList<Airport> filteredList = filterAirports(airports, airport); 
    intent.putExtra(SELECTED_AIRPORT_KEY, airport); 
    intent.putParcelableArrayListExtra(ALL_FLIGHTS_LIST_KEY, filteredList); 
    startActivityForResult(intent, NEW_FLIGHT_RESULT); // Here start for result 
} 


@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
    if(requestCode == NEW_FLIGHT_RESULT){ 
     if(resultCode == RESULT_OK) { 
      Flight f = data.getParcelableExtra("NEW_FILGHT_DATA"); 
      // Here add the new flight to the airport object you are maintaining !!! 
     } 
    } 

從ActivityArrivalFlights:

@Override 
public void onBackPressed() { 

    // You can wrap this with: If(newFlightsAdded()) { ... }: 
    Intent output = new Intent(); 
    output.putExtra("NEW_FILGHT_DATA", newFlight); 
    setResult(RESULT_OK, output); 
    finish(); 
} 

這是整個概念,我想你英里ssed,我的代碼是快速和骯髒的,所以清理它並根據需要使用。

注意! :在使用intent的活動之間傳遞對象(intent.putExtra(...)將傳遞一個對象的副本而不是同一個對象)。

+0

謝謝,但這不是我所期待的。我知道這個概念。 想法是,我將機場對象的參考傳遞給ActivityArrivalFlights活動。對同一個對象所做的任何更改應該在任何地方都可見,因爲它是同一個對象,我只是通過它的引用。讓我想到的是爲什麼這些變化在主要活動中不可見。 –

+0

@DraganApostolski intent.putExtra傳遞對象的副本,而不是對象本身,這意味着通過任何類型的intent.getExtra接收到的對象上的某些東西將改變對象的副本。您可以通過使airporst靜態(僅用於測試)來檢查對象是否爲副本,並將putExtra中傳遞的對象與原始靜態對象(在MainActivity中定義)進行比較,比較refs:airports == intentAirports。所以好的做法就是像上面提到的那樣返回新航班。 – Mercury

+0

我真的沒有閱讀這個方法的文檔,我真的認爲intent.putExtra傳遞一個引用。謝謝,現在知道我會找到一個解決方案。 –

相關問題