Kết thúc hoạt động hiện tại từ một phân đoạn


96

Tôi có một phân đoạn trong một hoạt động mà tôi đang sử dụng làm ngăn điều hướng. Nó chứa các nút mà khi được nhấp vào sẽ bắt đầu các hoạt động mới (startActivity từ một phân đoạn chỉ đơn giản gọi startActivity trên hoạt động hiện tại).

Đối với cuộc sống của tôi, tôi dường như không thể tìm ra cách tôi sẽ hoàn thành hoạt động hiện tại sau khi bắt đầu một hoạt động mới.

Tôi đang tìm cách đạt được thứ như thế này trong mảnh:

@Override
public void onClick(View view) {
    // TODO Auto-generated method stub
    if (view == mButtonShows) {
        Intent intent = new Intent(view.getContext(), MyNewActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    } 
}

Nhưng có vẻ như Fragment.class không triển khai finish () (giống như nó triển khai startActivity (...)).

Tôi muốn ngăn chặn hoạt động được xóa khi họ khởi chạy hoạt động thứ hai. (vì vậy nhấn lùi từ hoạt động mới về mặt kỹ thuật sẽ đưa chúng trở lại trình khởi chạy)

Câu trả lời:


277

Khi làm việc với các phân đoạn, thay vì sử dụng thishoặc tham chiếu đến ngữ cảnh, hãy luôn sử dụng getActivity(). Bạn nên gọi

getActivity().finish();

để hoàn thành hoạt động của bạn từ phân đoạn.


12
getActivity()có thể được nulltrong một số trường hợp. Chúng ta nên làm gì tiếp theo?
Matjaz Kristl

3
@ user983956 Trong những trường hợp như vậy, hoạt động đã bị hủy, vì vậy đừng gọi finish.
Cristian

2
Như một mẹo: getActivity có thể được null nếu bạn cố gắng sử dụng nó trước khi lạm phát quan điểm
csanonymus

1
Activity phải là controller / incharge chứ không phải là phân mảnh, bạn nên gọi lại Activity thông qua giao diện gọi lại và để Activity quyết định xem nó có tự kết thúc hay không.
Ahmed

1
Ngoài ra, nếu bạn có các singleton được đưa vào trong hoạt động, đừng quên phá hủy chúng, nó sẽ tạo ra rò rỉ bộ nhớ, hoặc nếu có lệnh gọi lại, hãy loại bỏ chúng. , if (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). tiêu diệt (); }
omersem

26

Thực ra thì ...

Tôi sẽ không để Fragment cố gắng hoàn thành Hoạt động. Theo ý kiến ​​của tôi, điều đó đặt quá nhiều quyền hạn vào Fragment. Thay vào đó, tôi sẽ sử dụng hướng dẫn tại đây: http://developer.android.com/training/basics/fragment/communicating.html

Yêu cầu Fragment xác định một giao diện mà Activity phải triển khai. Gọi cho Hoạt động, sau đó để Hoạt động quyết định phải làm gì với thông tin. Nếu hoạt động muốn tự kết thúc, thì nó có thể.


2
Đó là một điểm tốt, vì một hoạt động đơn lẻ có thể có nhiều phân đoạn. Như bạn đã đề cập, cách ưa thích để một phân mảnh giao tiếp trở lại hoạt động của nó là thông qua một giao diện.
Sasquatch

11

Như đã đề cập bởi Jon F Hancock , đây là cách một mảnh có thể 'đóng' hoạt động bằng cách đề xuất hoạt động đóng. Điều này làm cho phân mảnh di động như là lý do cho chúng. Nếu bạn sử dụng nó trong một hoạt động khác, bạn có thể không muốn đóng hoạt động đó.

Đoạn mã dưới đây là đoạn mã từ một hoạt động và phân đoạn có nút lưu và hủy.

PlayerActivity

public class PlayerActivity extends Activity 
    implements PlayerInfo.PlayerAddListener {

    public void onPlayerCancel() {
       // Decide if its suitable to close the activity, 
       //e.g. is an edit being done in one of the other fragments?
       finish();
    }
}

PlayerInfoFragment, chứa một giao diện mà hoạt động gọi cần triển khai.

public class PlayerInfoFragment extends Fragment {
   private PlayerAddListener callback; // implemented in the Activity

   @Override
   public void onAttach(Activity activity) {
     super.onAttach(activity);
     callback= (PlayerAddListener) activity;
   }

   public interface PlayerAddListener {
       public void onPlayerSave(Player p); // not shown in impl above
       public void onPlayerCancel();
   }

   public void btnCancel(View v) {
      callback.onPlayerCancel(); // the activity's implementation
   }
}

1

Mỗi khi tôi sử dụng finish để đóng phân mảnh, toàn bộ hoạt động sẽ đóng lại. Theo tài liệu, các phân đoạn sẽ vẫn còn miễn là hoạt động chính vẫn còn.

Thay vào đó, tôi thấy rằng tôi có thể thay đổi chế độ xem trở lại hoạt động chính bằng cách sử dụng câu lệnh này: setContentView (R.layout.activity_main);

Điều này đưa tôi trở lại hoạt động của cha mẹ.

Tôi hy vọng rằng điều này sẽ giúp những người khác có thể đang tìm kiếm điều này.


1

Rất đơn giản...

1- chỉ lấy hoạt động getActivity()trong phân đoạn

2- sau đó gọi finish();

Vì vậy, chỉ getActivity().finish();sẽ kết thúc hoạt động cha mẹ.


1

Bạn nên sử dụng phương thức getActivity () để kết thúc hoạt động từ phân mảnh.

getActivity().finish();

1

Trong Fragment sử dụng getActivity.finishAffinity ()

getActivity().finishAffinity();

Nó cũng sẽ loại bỏ tất cả các phân đoạn được đẩy bởi hoạt động hiện tại khỏi Ngăn xếp có Hoạt động ...


finishAffinity () sẽ xóa tất cả các hoạt động có cùng mối quan hệ, vì vậy các hoạt động bên dưới hoạt động hiện tại có chứa phân đoạn trong ngăn xếp cũng có thể được kết thúc.
Zakaria M. Jawas

0

Thử cái này. Không nên có bất kỳ cảnh báo nào ...

            Activity thisActivity = getActivity();
            if (thisActivity != null) {
                startActivity(new Intent(thisActivity, yourActivity.class)); // if needed
                thisActivity.finish();
            }

0

Ngày 15 tháng 6 năm 2020 - Câu trả lời được cập nhật.

Bạn có hai tùy chọn cho Java và Kotlin. Tuy nhiên, logic của cả hai cách đều giống nhau. Bạn nên gọi hoạt động sau khi gọi phương thức finish () .

Câu trả lời cho Kotlin ,

Nếu hoạt động của bạn không thể trống, hãy sử dụng Answer_1 . Tuy nhiên, nếu hoạt động của bạn có thể là trống , hãy sử dụng Answer_2 .

Answer_1: activity!!.finish()
Answer_2: activity?.finish()

Câu trả lời cho Java,

getActivity().finish();

@canerkaseler


-1

cố gắng sử dụng cái này

vâng Fragment.classkhông thực hiệnfinish()

Khi làm việc với các phân đoạn, thay vì sử dụng điều này hoặc tham chiếu đến ngữ cảnh, hãy luôn sử dụng getActivity(). Bạn nên gọi


11
Nói cho tôi biết diference giữa câu trả lời của bạn và câu trả lời đầu tiên ở trên (bởi @ coder_For_Life22) ...
Filipe Brito

Dont
it
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.