私のコードには空港とフライト(出発と到着)の2つの基本クラスがあります。空港は、到着する飛行オブジェクトのリストと出発飛行オブジェクトのリストで構成されています。 私の主な活動では、私は空港オブジェクトのリストを保持し、それらをリストビューで表します。リストビューオブジェクトに触れると、その空港オブジェクト(ActivityArrivalFlights)のすべての到着フライトを表示するための新しいアクティビティが開始されます。ここで空港オブジェクトをフィールドとして保持します。このアクティビティでは、同じ対象物に到着フライトを追加する機能があります。私はリストビューでもフライトを表し、アレイアダプター経由でフライトを追加します。他のアクティビティで作成されたオブジェクトは、メインアクティビティでは表示されません
問題はこれです。飛行オブジェクトが作成されて空港に追加されたとき、そのアクティビティが有効な限り存在します。 ActivityArrivalFlightsが破棄され、フォーカスがメインアクティビティにある場合、以前に追加された飛行オブジェクトはその空港にはありません。
ここに2つのアクティビティのコードがあります。私が何か間違っているか誰にでも教えてもらえますか?
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();
}
}
}
}
ありがとうございますが、これは私が探していたものではありません。私はこの概念を知っています。 アイデアは空港オブジェクトの参照をActivityArrivalFlightsアクティビティに渡すことです。同じオブジェクトに加えられた変更はどこでも見ることができます。なぜなら、同じオブジェクトなので、私はそれを参照するだけです。私が考えさせたのは、これらの変更が主な活動では見えない理由です。 –
@DraganApostolski intent.putExtraは、オブジェクトのコピーを渡しますが、オブジェクト自体ではなく、intent.getExtraによって受け取られたオブジェクトの何かを変更すると、オブジェクトコピーが変更されます。 airportをstatic(テストのみ)にし、putExtraで渡されたオブジェクトを(MainActivityで定義されている)元の静的オブジェクトと比較することで、オブジェクトが実際にコピーであるかどうかを確認し、airports == intentAirportsのようなrefを比較することができます。だから、上のように結果として新しい飛行機に戻ることが良い習慣です。 – Mercury
私はこのメソッドに関するドキュメントを実際に読んでいない、私は本当にintent.putExtraが参照を渡すと思った。ありがとう、今私は解決策を見つけることを知っている。 –