当前位置: 首页 > 知识库问答 >
问题:

在其他活动中创建的对象在主活动中不可见

郑向阳
2023-03-14

我的代码中有两个基本类:Airport和Flight(出发和到达)。机场由抵港飞行物清单和离港飞行物清单组成。在我的主要活动中,我持有一个airport对象列表,并在列表视图中表示它们。轻触列表视图对象,我启动了一个新的活动,用于显示该airport对象的所有到达航班(ActivityArrivalFlights),其中我将airport对象作为字段保存。在本练习中,有一个将到达航班添加到同一对象的功能。我也在列表视图中表示航班,并通过数组适配器添加航班。

问题是这样的:当一个飞行对象被创建并添加到机场时,只要活动是活动的,它就在那里。当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();
            }
        }
    }
}

共有1个答案

袁炳
2023-03-14

我看不出为什么在activityarrivalflights被破坏后,主活动会更新新的航班。

您不是为了将数据返回到MainActivity而将任何结果返回到MainActivity(从ActivityArrivalFlights返回),在您的情况下,返回已添加的航班,您需要执行以下操作:

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

注意!!!:使用intents在活动之间传递对象(intent.putExtra(...)将传递对象的副本,而不是同一个对象)。

 类似资料:
  • 问题内容: 我想从其他活动中调用主要活动中的公共方法。我怎样才能做到这一点? 问题答案: 这取决于。 在这种情况下,如果您只想使用某些共享功能(例如执行一些计算的代码)。 我建议将此共享功能移至某些独立的类,然后从那里进行调用。 在这种情况下,如果您想调用MainActivity,则MainActivity使用MainActivity UI进行了某些操作,则您必须使用Intent(http://d

  • 问题内容: 我在主要活动中创建了三个按钮。我为按钮一使用了以下代码 问题是当我按下后退按钮而不是在主要活动中不可见的按钮时。 问题答案: 如果您按下返回按钮,则会返回活动状态,但是您已经将按钮的可见性设置为“消失”,这就是为什么您看不到这些按钮的原因。您必须处理后退按钮,并将按钮的可见性再次设置为“可见”。

  • 问题内容: 有人知道如何从其他活动中关闭一个活动吗?例如:我有3个活动(活动A,B和C),并且可以从活动C中关闭活动A。我的活动结构是活动A->活动B->活动C如何从中关闭活动A活动C? 我曾尝试此代码: 但是该代码只能关闭活动B的活动A,而不能直接关闭活动C的活动A。 有谁知道直接从其他活动关闭活动?谢谢.. 问题答案:

  • 我有3个活动A、B和C。A导致B,B导致C。我希望能够在A和B之间来回移动,但我希望在C开始后完成A和B。我知道如何在通过意图启动C时关闭B,但在启动C时如何关闭A?

  • 用例:我正在开发一个Android应用程序,它有一个带有4个选项卡的视图页码,所有这些选项卡都是片段。对于每个选项卡/片段,我必须连接到具有 Oauth 的 REST Api,并且令牌每 5 分钟过期一次。 当前解决方案:使用RxJava和retryWhen操作符,我可以在收到401 HTTP错误时重新进行身份验证。对于订阅和消费的每个可观察流,使用: 因此,当令牌到期时,流将使用它,然后执行真正

  • 下面的第一个代码块是我的主要活动,我在其中创建了第二个活动的意图。在这个活动中,我将在列表视图中显示费用,因为它还没有完全实现,所以我暂时忽略了它。我想做的就是启动第二个活动,让用户输入详细信息,然后按下一个按钮将活动添加到列表视图中。@override公共布尔onOptionsItemSelected(MenuItem item){int id=item.getItemId(); 这是用户输入数