Android phủ lên một chế độ xem trên tất cả mọi thứ?


75

Bạn có thể phủ một chế độ xem lên trên mọi thứ trong Android không?

Trong iPhone, tôi sẽ nhận được chế độ xem mới được đặt thành frame.origin(0,0) và chiều rộng và chiều cao của nó thành chiều rộng và chiều cao của self.view. Việc thêm nó vào self.viewsau đó sẽ khiến nó hoạt động như một lớp phủ, che phủ nội dung phía sau (hoặc nếu nó có nền trong suốt thì hiển thị khung cảnh phía sau).

Có một kỹ thuật tương tự trong Android không? Tôi nhận ra rằng các chế độ xem hơi khác nhau (có ba loại (hoặc nhiều hơn ...) loại tương đối, tuyến tính và khung) nhưng có cách nào để chỉ chồng một chế độ xem lên trên mọi thứ một cách bừa bãi không?

Câu trả lời:


101

Đơn giản chỉ cần sử dụng RelativeLayouthoặc FrameLayout. Chế độ xem con cuối cùng sẽ phủ lên mọi thứ khác.

Android hỗ trợ một mẫu mà Cocoa Touch SDK không có: Quản lý bố cục.
Bố cục cho iPhone có nghĩa là đặt mọi thứ vào vị trí tuyệt đối (bên cạnh một số yếu tố căng thẳng). Bố cục trong android có nghĩa là trẻ em sẽ được đặt trong mối quan hệ với nhau.

Ví dụ (EditText thứ hai sẽ bao gồm hoàn toàn cái đầu tiên):

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/root_view">

    <EditText
        android:layout_width="fill_parent"
        android:id="@+id/editText1"
        android:layout_height="fill_parent">
    </EditText>

    <EditText
        android:layout_width="fill_parent"
        android:id="@+id/editText2"
        android:layout_height="fill_parent">
        <requestFocus></requestFocus>
    </EditText>

</FrameLayout>

FrameLayoutlà một số loại khung nhìn. Dành cho những trường hợp đặc biệt.

RelativeLayoutlà khá mạnh mẽ. Bạn có thể xác định các quy tắc như Chế độ xem A phải căn chỉnh bố cục gốc dưới cùng , Chế độ xem B phải căn chỉnh A từ dưới lên trên , v.v.

Cập nhật dựa trên nhận xét

Thông thường bạn đặt nội dung bằng setContentView(R.layout.your_layout)in onCreate(nó sẽ làm tăng bố cục cho bạn). Bạn có thể làm điều đó theo cách thủ công và gọi điện setContentView(inflatedView), không có sự khác biệt.

Bản thân chế độ xem có thể là một chế độ xem đơn (giống như TextView) hoặc một cấu trúc phân cấp bố cục phức tạp (các bố cục lồng nhau, vì tất cả các bố cục đều là các chế độ xem).

Sau khi gọi setContentViewhoạt động của bạn sẽ biết nội dung của nó trông như thế nào và bạn có thể sử dụng (FrameLayout) findViewById(R.id.root_view)để truy xuất bất kỳ chế độ xem nào trong hệ thống phân cấp này (Mẫu chung (ClassOfTheViewWithThisId) findViewById(R.id.declared_id_of_view)).


Ah cảm ơn vì ví dụ. Vì vậy, tôi đoán trong một hoạt động, chế độ xem nội dung có thể là một framelayout? Nếu tôi sử dụng a layoutinflaterđể lấy một relativelayouttệp xml bố cục, làm cách nào để thêm nó vào chế độ xem nội dung? Có cách nào để tham chiếu đến chế độ xem nội dung không? Cảm ơn
Thomas Clayson

Tôi đã cập nhật câu trả lời của mình, vì vậy nó giải thích nội dung của một hoạt động là gì và cách tương tác với nó.
Knickedi

Xuất sắc. Cảm ơn rât nhiều. :)
Thomas Clayson

1
Tôi muốn chỉ ra rằng mặc dù tôi thích FrameLayoutdo tính chất nhẹ của nó, nhưng nó không truyền được chiều cao đo được tối đa (hay còn gọi là chiều cao kết quả của chính nó) cho con cái của nó trong trường hợp match_parentchiều cao, xem tại đây . Do đó, khi hỗ trợ Android 2 và làm việc với match_parent, RelativeLayoutlà lựa chọn làm việc duy nhất; cho một ví dụ xem ở đây .
lớp xếp chồng

JFYI: Ở Android 4.4.4 đối với tôi, chỉ cần đặt một phân mảnh làm lớp phủ là đủ. Kể từ Android 5.0, một số yếu tố như nút và chế độ xem thẻ được đặt ở trên cùng. Với giải pháp trong câu trả lời, nó hoạt động như một sự quyến rũ.
ray

16
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<LinearLayout
    android:id = "@+id/Everything"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <!-- other actual layout stuff here EVERYTHING HERE -->

   </LinearLayout>

<LinearLayout
    android:id="@+id/overlay"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="right" >
</LinearLayout>

Bây giờ bất kỳ chế độ xem nào bạn thêm trong LinearLayout với android:id = "@+id/overlay"sẽ xuất hiện dưới dạng lớp phủ có trọng lực = ngay trên Bố cục tuyến tính với android:id="@+id/Everything"


10

Bạn có thể sử dụng bringToFront:

    View view=findViewById(R.id.btnStartGame);
    view.bringToFront();

9

Cách tốt nhất là ViewOverlay , Bạn có thể thêm bất kỳ lớp phủ nào có thể vẽ được vào bất kỳ chế độ xem nào làm lớp phủ của nó kể từ Android JellyBeanMR2 (Api 18).

Thêm mMyDrawablevào mMyViewlàm lớp phủ của nó:

mMyDrawable.setBounds(0, 0, mMyView.getMeasuredWidth(), mMyView.getMeasuredHeight())
mMyView.getOverlay().add(mMyDrawable)

typo: mMyDrawable.setBounds
yk4ever

Cảm ơn giải pháp của bạn. Nhưng bạn có thể truy cập các thành phần xem từ hình ảnh. Ví dụ: nếu có một nút trong chế độ xem của bạn nếu bạn nhấp vào hình ảnh, thì nút chế độ xem ban đầu sẽ được nhấp tự động.
Ranjith Subramaniam

@RanjithSubramaniam Có, vì nó chỉ là lớp phủ có thể vẽ được vẽ trên chế độ xem.
Jacks Gong

Nhưng nó sẽ không làm việc trong trường hợp một cái nhìn phải được đặt lên hàng đầu của người khác như đối tượng vẽ được chỉ là một đồ họa
Neeraj Sewani

0

Tôi đã thử các awnsers trước đây nhưng điều này không hoạt động. Bây giờ tôi jsut đã sử dụng LinearLayout thay vì TextureView, bây giờ nó đang hoạt động mà không có vấn đề gì. Hy vọng nó sẽ giúp một số người khác có cùng vấn đề. :)

    view = (LinearLayout) findViewById(R.id.view); //this is initialized in the constructor
    openWindowOnButtonClick();

public void openWindowOnButtonClick()
{
    view.setAlpha((float)0.5);
    FloatingActionButton fb = (FloatingActionButton) findViewById(R.id.floatingActionButton);
    final InputMethodManager keyboard = (InputMethodManager) getSystemService(getBaseContext().INPUT_METHOD_SERVICE);
    fb.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            // check if the Overlay should be visible. If this value is false, it is not shown -> show it.
            if(view.getVisibility() == View.INVISIBLE)
            {
                view.setVisibility(View.VISIBLE);
                keyboard.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
                Log.d("Overlay", "Klick");
            }
            else if(view.getVisibility() == View.VISIBLE)
            {
                view.setVisibility(View.INVISIBLE);
                keyboard.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
            }

1
Tôi nghĩ để làm cho câu trả lời này thực sự hữu ích, bạn nên bổ sung thêm một chút. Mã ví dụ, ảnh chụp màn hình, ...
GhostCat

0

Tôi vừa thực hiện một giải pháp cho nó. Tôi đã tạo một thư viện để làm điều đó theo cách có thể tái sử dụng, đó là lý do tại sao bạn không cần mã hóa lại trong XML của mình. Đây là tài liệu về cách sử dụng nó trong JavaKotlin . Đầu tiên, khởi tạo nó từ một hoạt động từ nơi bạn muốn hiển thị lớp phủ-

AppWaterMarkBuilder.doConfigure()
                .setAppCompatActivity(MainActivity.this)
                .setWatermarkProperty(R.layout.layout_water_mark)
                .showWatermarkAfterConfig();

Sau đó, bạn có thể ẩn và hiển thị nó từ bất kỳ đâu trong ứng dụng của mình -

  /* For hiding the watermark*/
  AppWaterMarkBuilder.hideWatermark() 

  /* For showing the watermark*/
  AppWaterMarkBuilder.showWatermark() 

Xem trước gif -

xem trước

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.