Tôi có một DialogFragment
để hiển thị View
như màn hình bật lên. Cửa sổ xuất hiện luôn ở giữa màn hình. Có cách nào để đặt vị trí của cửa sổ DialogFragment
không? Tôi đã xem xét source code nhưng chưa thể tìm thấy bất kỳ nội dung gì.Vị trí của DialogFragment trong Android
Trả lời
Hãy thử một cái gì đó như thế này:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
getDialog().getWindow().setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
WindowManager.LayoutParams p = getDialog().getWindow().getAttributes();
p.width = ViewGroup.LayoutParams.MATCH_PARENT;
p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
p.x = 200;
...
getDialog().getWindow().setAttributes(p);
...
hoặc các phương pháp khác cho getDialog().getWindow()
.
đảm bảo đặt vị trí sau khi gọi nội dung được đặt.
Tôi đang sử dụng lớp PopupWindow cho mục đích này vì bạn có thể chỉ định vị trí và kích thước của chế độ xem.
PopupWindow không phải là một mảnh, vì vậy đây là một cơn đau đầu. –
getDialog().getWindow()
sẽ không hoạt động đối với DialogFragment
dưới dạng getWindow()
sẽ trả về null nếu hoạt động lưu trữ không hiển thị, không phải là bạn đang viết một ứng dụng dựa trên phân đoạn. Bạn sẽ nhận được NullPointerException
khi bạn thử getAttributes()
.
Tôi khuyên bạn nên trả lời của Mobistry. Nếu bạn đã có một lớp DialogFragment, nó không quá khó để chuyển đổi. Chỉ cần thay thế phương thức onCreateDialog bằng phương thức xây dựng và trả về một PopupWindow. Sau đó, bạn sẽ có thể sử dụng lại Chế độ xem bạn cung cấp cho AlertDialog.builder.setView()
và gọi (PopupWindow object).showAtLocation()
.
Phải, tôi đập đầu vào tường trong một hoặc hai giờ với điều này, trước khi cuối cùng nhận được DialogFragment
vị trí như tôi muốn.
Tôi đang xây dựng trên Steelight's answer tại đây. Đây là phương pháp đơn giản nhất, đáng tin cậy nhất mà tôi tìm thấy.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) {
Window window = getDialog().getWindow();
// set "origin" to top left corner, so to speak
window.setGravity(Gravity.TOP|Gravity.LEFT);
// after that, setting values for x and y works "naturally"
WindowManager.LayoutParams params = window.getAttributes();
params.x = 300;
params.y = 100;
window.setAttributes(params);
Log.d(TAG, String.format("Positioning DialogFragment to: x %d; y %d", params.x, params.y));
}
Lưu ý rằng params.width
và params.softInputMode
(được sử dụng trong câu trả lời của Steelight) không liên quan cho việc này.
Dưới đây là ví dụ hoàn chỉnh hơn. Điều tôi thực sự cần là sắp xếp hộp thoại "xác nhận" DialogFragment bên cạnh chế độ xem "nguồn" hoặc "cha mẹ", trong trường hợp của tôi là ImageButton.
Tôi đã chọn sử dụng DialogFragment, thay vì bất kỳ Fragment tùy chỉnh nào, vì nó cung cấp cho bạn tính năng "hộp thoại" miễn phí (hộp thoại đóng khi người dùng nhấp vào bên ngoài nó, v.v.).
Ví dụ ConfirmBox trên "nguồn" ImageButton của nó (thùng rác)
/**
* A custom DialogFragment that is positioned above given "source" component.
*
* @author Jonik, https://stackoverflow.com/a/20419231/56285
*/
public class ConfirmBox extends DialogFragment {
private View source;
public ConfirmBox() {
}
public ConfirmBox(View source) {
this.source = source;
}
public static ConfirmBox newInstance(View source) {
return new ConfirmBox(source);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_FRAME, R.style.Dialog);
}
@Override
public void onStart() {
super.onStart();
// Less dimmed background; see https://stackoverflow.com/q/13822842/56285
Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.dimAmount = 0.2f; // dim only a little bit
window.setAttributes(params);
// Transparent background; see https://stackoverflow.com/q/15007272/56285
// (Needed to make dialog's alpha shadow look good)
window.setBackgroundDrawableResource(android.R.color.transparent);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Put your dialog layout in R.layout.view_confirm_box
View view = inflater.inflate(R.layout.view_confirm_box, container, false);
// Initialise what you need; set e.g. button texts and listeners, etc.
// ...
setDialogPosition();
return view;
}
/**
* Try to position this dialog next to "source" view
*/
private void setDialogPosition() {
if (source == null) {
return; // Leave the dialog in default position
}
// Find out location of source component on screen
// see https://stackoverflow.com/a/6798093/56285
int[] location = new int[2];
source.getLocationOnScreen(location);
int sourceX = location[0];
int sourceY = location[1];
Window window = getDialog().getWindow();
// set "origin" to top left corner
window.setGravity(Gravity.TOP|Gravity.LEFT);
WindowManager.LayoutParams params = window.getAttributes();
// Just an example; edit to suit your needs.
params.x = sourceX - dpToPx(110); // about half of confirm button size left of source view
params.y = sourceY - dpToPx(80); // above source view
window.setAttributes(params);
}
public int dpToPx(float valueInDp) {
DisplayMetrics metrics = getActivity().getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}
}
Đó là khá dễ dàng để làm cho tổng quát sử dụng trên bằng cách thêm các thông số constructor hoặc setters khi cần thiết. (My thức ConfirmBox
có một nút theo kiểu (bên trong một số biên giới vv) có văn bản và View.OnClickListener
thể được tùy chỉnh trong mã.)
Tôi đã tìm thấy câu trả lời hay nhất tuyệt vời. –
Các bạn rock - cảm ơn - Tôi rất tò mò, ** tại sao tôi không thể chỉ thiết lập điều này trong XML của phân đoạn? ** Tôi không hiểu gì về một dev dev iOS? cảm ơn các ông! :) – Fattie
Câu trả lời của Grt !! Tôi gặp bất kỳ vấn đề nào, trong kịch bản nút nguồn của tôi (dưới đây là đoạn hộp thoại sẽ được hiển thị) thay đổi vị trí trên thay đổi hướng màn hình, do đó, việc thay đổi hướng hộp thoại không cập nhật vị trí theo vị trí của ' nguồn'. Bạn có thể vui lòng cho tôi một số gợi ý về cách thực hiện điều này không. – Dory
Bạn cần phải ghi đè phương pháp onResume() trong DialogFragment của bạn như sau:
@Override
public void onResume() {
final Window dialogWindow = getDialog().getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.x = 100; // set your X position here
lp.y = 200; // set your Y position here
dialogWindow.setAttributes(lp);
super.onResume();
}
- 1. Android findViewById trong DialogFragment
- 2. vị trí hiện tại của gps android
- 3. Nhận vị trí của người dùng Android
- 4. Cách tính từ vị trí của tôi đến vị trí đích trong android
- 5. Lấy vị trí của một spinner trong Android
- 6. Tìm vị trí/Vị trí của JFrame trong cửa sổ
- 7. Dừng trình nghe vị trí trong Android
- 8. Sửa vị trí tuyệt đối trong Android
- 9. Vị trí của @classmethod
- 10. Vị trí của Microsoft.Sharepoint.dll
- 11. Thanh tiến trình Android DialogFragment
- 12. Android canvas drawText y-vị trí của văn bản
- 13. Tìm vị trí Xem (vị trí) trên màn hình (màn hình) trong android
- 14. Android: vị trí tuyệt đối của Thẻ sd bên ngoài
- 15. Vị trí của symchk
- 16. Vị trí của WSDL.exe
- 17. Vị trí hoạt động của hộp thoại android
- 18. Vị trí thiết lập Android của scrollbox hortizontal
- 19. Tìm hiểu vị trí của các vị trí khác nhau
- 20. Android - Chỉ nhận vị trí một lần
- 21. Android: tắt các nút OK/Hủy DialogFragment
- 22. Xác minh vị trí mảng chuỗi Android
- 23. Android: Hoạt hình Xem vị trí
- 24. Hướng dẫn vị trí trên Android GEO
- 25. Android RelativeLayout - cách đặt vị trí?
- 26. Cách nhận vị trí GPS Android
- 27. Vị trí của biểu tượng trong QTreeWidgetItem
- 28. Vị trí của head.phtml trong Magento
- 29. Vị trí của chuỗi con trong NSString
- 30. Nhận vị trí của JPopupMenu
nhờ Steelight Tôi upvoted câu trả lời của bạn. Tôi có một câu hỏi mặc dù.Tại sao bạn thay đổi WindowManager.LayoutParam p? setGravity() dường như làm thủ thuật để thiết lập cửa sổ ở trên cùng. Có vẻ như không có bất kỳ tác dụng phụ nào trên LayoutParams khi tôi kiểm tra nó hoặc khi tôi đọc tài liệu về setGravity. – flobacca
Câu hỏi đặt ra là "cách đặt vị trí", tôi không cho rằng anh ta có nghĩa là 'hàng đầu', vì vậy tôi đã đưa ra ví dụ về việc thiết lập nhiều thuộc tính để có được hiệu ứng mong muốn. – Steelight
+1 vì điều này cho tôi thấy đúng hướng. Điều cuối cùng làm việc cho tôi: http://stackoverflow.com/a/20419231/56285 – Jonik