จะนำมุมมองต่อหน้าทุกสิ่งได้อย่างไร?


131

ฉันมีกิจกรรมและวิดเจ็ตจำนวนมากอยู่ในนั้นบางส่วนมีภาพเคลื่อนไหวและเนื่องจากภาพเคลื่อนไหวบางวิดเจ็ตจึงมีการเคลื่อนไหว (แปล) ซึ่งกันและกัน ตัวอย่างเช่นมุมมองข้อความกำลังเคลื่อนผ่านปุ่มบางปุ่ม . .

ตอนนี้สิ่งที่ฉันต้องการให้ปุ่มอยู่ด้านหน้าเสมอ และเมื่อมุมมองข้อความเคลื่อนไหวฉันต้องการย้ายไปด้านหลังปุ่ม

ฉันไม่สามารถบรรลุสิ่งนี้ได้ฉันลองทุกอย่างที่ฉันรู้และ "bringToFront ()" ไม่ได้ผลแน่นอน

หมายเหตุฉันไม่ต้องการควบคุม z-order ตามลำดับของการวางองค์ประกอบในการจัดวางเพราะฉันทำไม่ได้ :) เลย์เอาต์มีความซับซ้อนและฉันไม่สามารถวางปุ่มทั้งหมดที่ขอทานของเค้าโครงได้


3
ฉันใช้ a ที่RelativeLayoutมีมุมมอง "ด้านบน" ปรากฏเป็นอันดับสุดท้ายใน XML ดูstackoverflow.com/a/31340762/1121497
Ferran Maylinch

ใครช่วยบอกรหัสที่เกี่ยวข้องใน xml ของ 'bringToFront'
Shirish Herwade

ลองใช้ระดับความสูง bottomView = ระดับความสูง: 1dp และ topView = ความสูง: 2dp ใน xml ของคุณ || ViewCompat.setElevation (View, int)
Tlacaelel Ramon Luis

คำตอบ:


144

คุณสามารถเรียก bringToFront () ในมุมมองที่คุณต้องการรับด้านหน้า

นี่คือตัวอย่าง:

    yourView.bringToFront();

4
ผลที่ไม่คาดคิด: ผมใช้ว่าในรูปแบบเชิงเส้นในแนวตั้งและมุมมอง bringed ไปด้านหน้าปรากฏที่ด้านล่าง ... ตัวอย่างเช่นผมมีA / B / Cและต้องการที่จะนำAไปข้างหน้าดังนั้นหลังจากที่ทำงานฉันสิ้นสุดขึ้นกับรูปแบบเช่นa.bringToFront() B / C / A
Ferran Maylinch

2
ดังนั้นฉันพบว่าLinearLayoutไม่สามารถใช้กับbringToFront. ฉันลงเอยด้วยการใช้ไฟล์RelativeLayout. ดูความคิดเห็นของฉันเกี่ยวกับคำถามนั้นเอง
Ferran Maylinch

1
ใครช่วยบอกรหัสที่เกี่ยวข้องใน xml ของ 'bringToFront'
Shirish Herwade

สิ่งนี้ส่งผลให้มีการจัดตำแหน่งใหม่ขององค์ประกอบที่ฉันย้ายไปด้านหน้าไม่ว่าด้วยเหตุผลใดก็ตาม ViewCompat.setTranslationZ(view, 1)ทำงานได้อย่างสมบูรณ์แบบในทางกลับกัน
Bimde

1
ถ้าฉันใช้ในรายการ android: theme = "@ android: style / Theme.Light.NoTitleBar" ในกิจกรรมกว่า yourView.bringToFront (); ทำงานได้อย่างสมบูรณ์ แต่ฉันใช้ android: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); ไม่ทำงาน เบาะแสใด ๆ เกี่ยวกับสิ่งนั้น
ราหุล

43

ฉันได้ตรวจสอบสแต็กโอเวอร์โฟลว์เพื่อหาคำตอบที่ดีและเมื่อฉันไม่พบสิ่งที่ฉันค้นหาในเอกสาร

ดูเหมือนจะไม่มีใครสะดุดกับคำตอบง่ายๆนี้:

ViewCompat.setTranslationZ(view, translationZ);

ค่าเริ่มต้นการแปล z คือ 0.0


นั่นคือตำแหน่งขององค์ประกอบบนแกน Z ในหน่วยพิกเซลหรือที่เรียกว่าการยกระดับ setTranslationX จะย้ายมุมมองไปตามแกน X (ซ้าย / ขวา) setTranslationY ตามแกน Y (บน / ล่าง) แกน Z คือแกนที่ 3
xdevs23

เกี่ยวกับอะไรsetZ()? ถ้าฉันจำได้ถูกต้องตำแหน่ง Z ของมุมมองคือความสูงบวกกับการแปล Z หลังจากทั้งหมด
Gensoukyou1337

2
@ Gensoukyou1337 จากนั้นใช้ ViewCompat.setZ(view, yourValueInPixels); view.setZ()งานได้กับ API 21 ขึ้นไปเท่านั้น
Johnny Five

1
ตรวจสอบโค้ด Java 8 ใน Android Studio - จะตรวจสอบว่า SDK_INT> = 21 เท่านั้นดังนั้นสำหรับ <21 api จะไม่มีผล
Vadim

32

วิธีแก้ปัญหาที่ง่ายกว่านั้นคือการแก้ไข XML ของกิจกรรม ใช้

android:translationZ=""

3
สิ่งนี้มีประโยชน์เฉพาะใน Android API 21 ขึ้นไป
isakbob

25

bringToFront()เป็นวิธีที่ถูกต้อง แต่โปรดทราบว่าคุณต้องเรียกใช้bringToFront()และinvalidate()วิธีการในมุมมองระดับสูงสุด (ภายใต้มุมมองรูทของคุณ) เช่น:

ลำดับชั้นของมุมมองของคุณคือ:

-RelativeLayout
|--LinearLayout1
|------Button1
|------Button2
|------Button3
|--ImageView
|--LinearLayout2
|------Button4
|------Button5
|------Button6

ดังนั้นเมื่อคุณเคลื่อนไหวกลับปุ่มของคุณ (1-> 6), ปุ่มของคุณจะอยู่ภายใต้ (ด้านล่าง) ImageViewเพื่อนำมันไป (ด้านบน) ImageViewคุณต้องเรียกbringToFront()และinvalidate()วิธีการในLinearLayouts จากนั้นมันจะทำงาน :) ** หมายเหตุ: อย่าลืมตั้งค่าandroid:clipChildren="false"สำหรับเค้าโครงรูทของคุณหรือ gradparent_layout ของมุมมองภาพเคลื่อนไหว ลองดูรหัสจริงของฉัน:

.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hw="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/common_theme_color"
    android:orientation="vertical" >

    <com.binh.helloworld.customviews.HWActionBar
        android:id="@+id/action_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_actionbar_height"
        android:layout_alignParentTop="true"
        hw:titleText="@string/app_name" >
    </com.binh.helloworld.customviews.HWActionBar>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/action_bar"
        android:clipChildren="false" >

        <LinearLayout
            android:id="@+id/layout_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>

        <ImageView
            android:id="@+id/imgv_main"
            android:layout_width="@dimen/common_imgv_height"
            android:layout_height="@dimen/common_imgv_height"
            android:layout_centerInParent="true"
            android:contentDescription="@string/app_name"
            android:src="@drawable/ic_launcher" />

        <LinearLayout
            android:id="@+id/layout_bottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

บางรหัสใน. java

private LinearLayout layoutTop, layoutBottom;
...
layoutTop = (LinearLayout) rootView.findViewById(R.id.layout_top);
layoutBottom = (LinearLayout) rootView.findViewById(R.id.layout_bottom);
...
//when animate back
//dragedView is my layoutTop's child view (i added programmatically) (like buttons in above example) 
dragedView.setVisibility(View.GONE);
layoutTop.bringToFront();
layoutTop.invalidate();
dragedView.startAnimation(animation); // TranslateAnimation
dragedView.setVisibility(View.VISIBLE);

กลุค!


จะเกิดอะไรขึ้นถ้าคุณต้องการเพียงแค่นำปุ่ม 6 มาไว้เหนือมุมมองภาพไม่ใช่ปุ่มอื่น ๆ ?
Adam Katz

@AdamKatz: ฉันคิดว่าคุณต้องจัดพวกมันใหม่ให้เป็นอีกระดับหนึ่ง จากนั้นนำไปในแบบของคุณ
Justin

ขอบคุณฉันพยายามนำมุมมองรีไซเคิลเพียงรายการเดียวมาไว้เหนือมุมมอง แต่ปล่อยให้รายการอื่น ๆ อยู่ด้านล่างติดอยู่!
Adam Katz

ผมใช้เหมือนกัน มันทำงานได้ดีกับปัญหาเดียวที่ซ่อนแถบเครื่องมือ
user2980181

สิ่งนี้ใช้ได้กับหลายระดับหรือไม่? สมมติว่าฉันมี a ConstraintLayoutที่มี a RelativeLayoutและอีกRelativeLayoutอันมีขนาดเท่ากับรูทConstraintLayout( match_parent) อันแรกRelativeLayoutมี a Buttonและอยู่หลัง (z-order-wise) อันที่สองRelativeLayoutด้วย ฉันสามารถทำให้Buttonในครั้งแรกRelativeLayoutดูเหมือนว่ามันอยู่ด้านบนของทุกสิ่งเช่นที่สามารถมองเห็นและคลิกได้โดยใช้View::bringToFront()?
oaskamay

25

ด้วยรหัสนี้ใน xml

 android:translationZ="90dp"

3
ในกรณีที่ไม่90dpมาจากไหน?
Sudhir Khanger

1
เป็นการป้อนข้อมูลด้วยตนเอง คุณสามารถลองใช้ตามความต้องการของคุณ 45dp หรือ 135dp หรือ 180dp หรือ 270dp
กฤษณะ

คุณใช้ 1dp ไม่ได้เหรอ
Tyler Turnbull

18

ลองFrameLayoutทำให้คุณมีความเป็นไปได้ที่จะทำให้มุมมองเหนือมุมมองอื่น ๆ คุณสามารถสร้างสองLinearLayouts: หนึ่งที่มีมุมมองพื้นหลังและหนึ่งที่มีมุมมองเบื้องหน้าและรวมเข้าด้วยกันโดยใช้ไฟล์FrameLayout. หวังว่านี่จะช่วยได้


1
เราจะนำมันไปสู่จุดสูงสุดเหมือนไดอะล็อกได้อย่างไร?
Gaurav Arora

@Infinity คุณสามารถสร้าง FragmentDialog เพื่อจุดประสงค์นี้หรือเพียงแค่ใช้ Theme.Dialog สำหรับกิจกรรมของคุณ
Egor

ฉันไม่สามารถใช้ FragmentDialog ได้เนื่องจากมันเข้ากันไม่ได้กับ API 10 ประการที่สองฉันใช้ธีมสำหรับแอปพลิเคชันของฉันอยู่แล้ว มีวิธีอื่น ๆ ? ฉันเคยใช้ FrameLayout เหมือนที่คุณพูด!
Gaurav Arora

@Infinity คุณสามารถใช้ FragmentDialog เวอร์ชันไลบรารีที่เข้ากันได้ซึ่งมีให้จาก API 4
Egor

8

หากคุณกำลังใช้ConstraintLayoutเพียงแค่วางองค์ประกอบไว้หลังองค์ประกอบอื่น ๆ เพื่อให้อยู่ด้านหน้ากว่าองค์ประกอบอื่น ๆ



3

อาจมีวิธีอื่นที่ช่วยประหยัดทั้งวัน เพียงแค่เริ่มต้นกล่องโต้ตอบใหม่ที่มีเค้าโครงที่ต้องการแล้วแสดง ฉันต้องการมันเพื่อแสดง loadView ผ่าน DialogFragment และนี่เป็นวิธีเดียวที่ฉันจะประสบความสำเร็จ

Dialog topDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
topDialog.setContentView(R.layout.dialog_top);
topDialog.show();

bringToFront () อาจไม่ทำงานในบางกรณีเช่นของฉัน แต่เนื้อหาของรูปแบบโต้ตอบ _top จะต้องแทนที่สิ่งใด ๆ บนเลเยอร์ ui แต่อย่างไรก็ตามนี่เป็นวิธีแก้ปัญหาที่น่าเกลียด


3

ฉันประสบปัญหาเดียวกัน วิธีแก้ปัญหาต่อไปนี้ได้ผลสำหรับฉัน

 FrameLayout glFrame=(FrameLayout) findViewById(R.id.animatedView);
        glFrame.addView(yourView);
        glFrame.bringToFront();
        glFrame.invalidate();

วิธีที่ 2 คือการใช้ xml เพิ่มแอตทริบิวต์นี้ในมุมมอง xml

android:translationZ=""

2

คุณสามารถใช้ BindingAdapter ดังนี้:

@BindingAdapter("bringToFront")
public static void bringToFront(View view, Boolean flag) {
    if (flag) {
        view.bringToFront();
    }
}


  <ImageView
        ...
        app:bringToFront="@{true}"/>

0

คุณต้องใช้ framelayout และวิธีที่ดีกว่าในการทำเช่นนี้คือการทำให้มองไม่เห็นเมื่อไม่ต้องการ นอกจากนี้คุณต้องกำหนดตำแหน่งสำหรับแต่ละมุมมองเพื่อที่พวกเขาจะย้ายไปตามตำแหน่งที่ตรงกัน


0

หากคุณกำลังใช้LinearLayoutคุณควรโทรmyView.bringToFront()และหลังจากที่คุณควรโทรparentView.requestLayout()และparentView.invalidate()บังคับให้ผู้ปกครองวาดใหม่ด้วยคำสั่งย่อยใหม่



0

ขอขอบคุณที่กองผู้ใช้มากกว่านี้คำอธิบายที่ผมได้ทำงานนี้แม้กระทั่งบน Android 4.1.1

((View)myView.getParent()).requestLayout();
myView.bringToFront();

ตัวอย่างเช่นในการใช้งานแบบไดนามิกของฉันฉันทำ

public void onMyClick(View v)
     {
     ((View)v.getParent()).requestLayout();
     v.bringToFront();
     }

และ Bamm!


-2

จัดเรียงตามลำดับที่คุณต้องการแสดง สมมติว่าคุณต้องการแสดงมุมมอง 1 ที่ด้านบนของมุมมอง 2 จากนั้นเขียนโค้ดมุมมอง 2 จากนั้นเขียนมุมมอง 1 โค้ด หากคุณไม่สามารถทำการสั่งซื้อนี้ได้ให้เรียก bringToFront () ไปที่มุมมองรูทของเค้าโครงที่คุณต้องการนำมาด้านหน้า


-32

คุณสามารถตั้งค่าการเปิดเผยเป็นเท็จของมุมมองอื่น ๆ

view1.setVisibility(View.GONE);
view2.setVisibility(View.GONE);
...

หรือ

view1.setVisibility(View.INVISIBLE);
view2.setVisibility(View.INVISIBLE);
...

และตั้งค่า

viewN.setVisibility(View.VISIBLE);

4
ฉันต้องการให้ทุกคนมองเห็นได้นั่นไม่ใช่ปัญหาปัญหาคือ z-order หากความมีชีวิตเป็นปัญหามันก็จะแก้ได้ง่าย . .
Lukap
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.