How to use LayoutInflater / ViewStub for an overlay

百般思念 提交于 2019-12-04 12:22:11

I have faced a similar problem, I client wanted a walkthrough of the application, where the entire screen had to become whiter (as they said: "transparent"), except for the button being explained by an overlay speech-bubble.
Fortunately for you, your layout is not nearly as complicated as the one I had to work with :)

Now, you can get the transparency-effect in two ways, either have a white background and call all the views setAlpha() methods, or you can create a half-transparent white overlay.
If you go with the overlay, you'll have to find a way to display the opaque buttons through the overlay. This can get a bit complicated. If you go with the first option, you can just setAlpha(1) on the opaque view to get it to show up.

The setAlpha() method is only available from api version 11+, so if you target an earlier version, you might have to do it in a slightly more complicated way.
Example of setting alpha on views pre-honeycomb:

Layout for your buttons (make them however you want, just make them similar so you can loop through them):

<LinearLayout 
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <ImageView 
        android:tag="image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/tile"/>
    <TextView 
        android:tag="text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FF000000"
        android:text="button1"/>
</LinearLayout>

In your program, when you are want to make the buttons transparent:

LinearLayout l = (LinearLayout) findViewById(R.id.button1);
((ImageView)l.findViewWithTag("image")).setAlpha(0x7F);
((TextView)l.findViewWithTag("text")).setTextColor(0x7F000000);



When you have decided on how you want to create the transparency effect, you will have to decide on how to display the overlay-text/bubble. You'll most likely want to put this in a separate layer on top of your entire layout, to make sure that it is not affected by your new view.
One way to achieve this is by changing your root layout element to a FrameLayout, and then creating/displaying in this. e.g:

<FrameLayout background="#FFFF"> <!-- white background, just in case -->
    <LinearLayout>
        <!-- the rest of your layout -->
    </LinearLayout>
    <LinearLayout visibility="gone"> <!-- this will be your overlay view -->
        <ImageView /> <!-- the arrow/ring -->
        <TextView /> <!-- the description -->
    </LinearLayout>
</FrameLayout>

When the introduction is displayed, you set the position of the hidden overlay-view to the position of the table item to be explained, change the text to an appropriate string/resource and display the view.

When the introduction is over, you reset the alpha values of all buttons, and set the visibility of the overlay to gone again.

Since I don't have much experience with ViewStub, I would do it with LayoutInflater.

First of all, you need to have a second layout loaded on top of your current layout. The easiest is to have a FrameLayout, which has as one child your current view, and the dynamically you load the second child on the first start. When you load a content view in an Activity, it will be attached to some already created views (some DecorView, a FrameLayout, etc). So you can either re-use the existing FrameLayout, or you can create a new one. I would vote for the second solution, since it's more stable (I just mentioned the other possibility in case you want to minimize the number of layers).

So, as a first step, wrap your current layout inside a FrameLayout, and give it an id, let's say "@id/root".

Then, in the onCreate method, you can have something like this:

setContentView(R.layout.main);
if (isFirstRun()) {
    ViewGroup parent = (ViewGroup)findViewById(R.id.root); // locate the FrameLayout
    LayoutInflater li = LayoutInflater.from(this); // get an instance of LayoutInflater
    li.inflate(R.layout.overlay, parent);
}

So far you will have the overlay loaded. Now it's up to you to define the overlay. To make the whitening effect, just set the following attribute on the root view in your overlay.xml layout:

android:background="#40ffffff"

To position the circle, first you need to find it's location. You can use the View.getLocationOnScreen to get the absolute coordinate of the icon (below the circle) on the screen. Then you can have two options:

  • either create a custom view (for the overlay) and manually draw the circle at the given location
  • or add the circle using an ImageView and adjust the left and top margins based on the coordinates
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!