0

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
cottonBallPaws
  • 21,220
  • 37
  • 123
  • 171

2 Answers2

2

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

Cheryl Simon
  • 46,552
  • 15
  • 93
  • 82
  • That worked perfectly. Thanks. Do you know a way to accomplish this without having to change the activities xml layout? All of the activities in my application will need this and it seems inefficient to have to wrap all of the activities' layouts into a framelayout in order to get this popup button to appear over them when needed. – cottonBallPaws Oct 21 '10 at 21:09
  • 2
    You could create a subclass of Activity that all of your Activities extend, and have some logic there to programatically insert the particular layout into a FrameLayout. – Cheryl Simon Oct 21 '10 at 21:21
1

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.

Whome
  • 10,181
  • 6
  • 53
  • 65