How to overlay a button programmatically?

2019-02-16 02:14发布

What I would like to accomplish is to, at runtime, place a button in the middle of the screen, as the very top layer, overlaying anything below it. (It's not big, so it will not completely cover the screen, just whatever happens to be below it.)

I looked at creating a custom dialog, however that blocks all other user input. I want all of the views below this new button to act normally and respond to the user, but I just want to add (and later remove) the button above everything.

Hopefully that makes sense. I'm just wondering what might be the best approach to look into?

2条回答
女痞
2楼-- · 2019-02-16 02:57

I had to overlay a simple layout programmatically on top of any visible activity. Normal activity layout xmls don't know anything about the overlay. Layout had one textview component but could have any structure you see fit. This is my overlay layout.

res/layout/identity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/identitylayout"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:layout_centerInParent="true" >

<TextView 
    android:id="@+id/identityview"
    android:padding="5dp"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:textColor="#FFFFFF" android:background="#FF6600"
    android:textSize="30dp"            
/>

</RelativeLayout>

Overlay is shown on top of the existing content, after timeout is deleted from the screen. Application calls this function to display overlay.

private void showIdentity(String tag, long duration) {
    // default text with ${xx} placeholder variables
    String desc = getString(R.string.identity);
    desc = desc.replace("${id}", reqId!=null ? reqId : "RequestId not found" );
    desc = desc.replace("${tag}", tag!=null ? tag : "" );
    desc = desc.trim();

    // get parent and overlay layouts, use inflator to parse
    // layout.xml to view component. Reuse existing instance if one is found.
    ViewGroup parent = (ViewGroup)findViewById(R.id.mainlayout);
    View identity = findViewById(R.id.identitylayout);
    if (identity==null) {
        LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        identity = inflater.inflate(R.layout.identity, parent, false);
        parent.addView(identity);
    }

    TextView text = (TextView)identity.findViewById(R.id.identityview);
    text.setText(desc);
    identity.bringToFront();

    // use timer to hide after timeout, make sure there's only
    // one instance in a message queue.
    Runnable identityTask = new Runnable(){
        @Override public void run() {
            View identity = findViewById(R.id.identitylayout);
            if (identity!=null)
                ((ViewGroup)identity.getParent()).removeView(identity);
        }
    };
    messageHandler.removeCallbacksAndMessages("identitytask");
    messageHandler.postAtTime(identityTask, "identitytask", SystemClock.uptimeMillis()+duration);
}

Timer messageHandler is member of main Activity instance (private Handler messageHandler) where I put all scheduled tasks. I am using Android 4.1 device lower than that I don't know what happens.

查看更多
小情绪 Triste *
3楼-- · 2019-02-16 02:58

Use a FrameLayout, with the button as it's 2nd child. Set it to GONE when you don't want it visible.

查看更多
登录 后发表回答