如何在Android中创建半透明的指令页面?

时间:2012-01-12 19:40:30

标签: android

我是Android新手并且在过去2天尝试解决此问题,但可以找到解决方案。任何帮助将受到高度赞赏。如何为Android Market中的App卡路里计数器创建一个半透明的指令页面?

Instruction page in Android

4 个答案:

答案 0 :(得分:33)

创建新活动并将顶级视图设置为具有半透明背景:

android:background="#c0000000"

编辑:您还需要声明活动具有透明背景。为清单中的活动设置此主题将起作用:

android:theme="@android:style/Theme.Translucent"

答案 1 :(得分:10)

我刚刚在我的一个项目中实施了Ted的答案。大!非常容易实现和美观的结果。非常感谢泰德。

但是,由于Stack Overflow用于获取和共享,我想分享我的自定义视图的实现,该视图以“针”的形式创建箭头,我使用Ted的方法来完成原始答案。这是代码:

package com.yourpackage;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;
import de.nantoka.miep.R;

public class CoachmarkArrow extends View {

    private static final float CIRCLE_RADIUS = 1.5f;
    private static final int TOPLEFT = 0;
    private static final int TOPRIGHT = 1;
    private static final int BOTTOMLEFT = 2;
    private static final int BOTTOMRIGHT = 3;

    Paint paint;
    int from, to;

    PointF padding = new PointF();
    PointF fromPoint = new PointF();
    PointF toPoint = new PointF();

    public CoachmarkArrow (Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CoachmarkArrow, 0, 0);

        getPaint(a);
        getFromTo(a);

        a.recycle();
    }

    private void getFromTo(TypedArray a) {

        from = a.getInt(R.styleable.CoachmarkArrow_from, BOTTOMLEFT);
        to = a.getInt(R.styleable.CoachmarkArrow_to, TOPLEFT);
    }

    private void getPaint(TypedArray a) {
        paint = new Paint();

        paint.setColor(a.getColor(R.styleable.CoachmarkArrow_color, Color.WHITE));
        paint.setStrokeWidth(a.getDimensionPixelSize(R.styleable.CoachmarkArrow_size, 0));

        paint.setStrokeCap(Paint.Cap.BUTT);
        paint.setAntiAlias(true);
    }

    @Override
    protected void onDraw (Canvas canvas){
        calculatePadding(canvas);
        calculateLinePoints();

        drawLine(canvas, fromPoint, toPoint);
        drawCircle(canvas, fromPoint);
    }

    private void calculateLinePoints() {
        fromPoint = getPoint(from);
        toPoint = getPoint(to);
    }

    private void calculatePadding(Canvas canvas) {

        padding.x = CIRCLE_RADIUS * paint.getStrokeWidth() / canvas.getWidth();
        padding.y = CIRCLE_RADIUS * paint.getStrokeWidth() / canvas.getHeight();
    }

    private PointF getPoint(int position) {
        PointF point = new PointF();

        if (position == TOPRIGHT || position == BOTTOMRIGHT){
            point.x = 1.0f - padding.x;
        }
        else {
            point.x = padding.x;
        }

        if (position == BOTTOMLEFT || position == BOTTOMRIGHT){
            point.y = 1.0f - padding.y;
        }
        else {
            point.y = padding.y;
        }       

        return point;
    }

    private void drawCircle(Canvas canvas, PointF fromPoint) {

        canvas.drawCircle(
                canvas.getWidth() * fromPoint.x, 
                canvas.getHeight() * fromPoint.y, 
                CIRCLE_RADIUS * paint.getStrokeWidth(), 
                paint
                );
    }

    private void drawLine(Canvas canvas, PointF fromPoint, PointF toPoint) {
        canvas.drawLine(
                canvas.getWidth() * fromPoint.x, 
                canvas.getHeight() * fromPoint.y, 
                canvas.getWidth() * toPoint.x, 
                canvas.getHeight() * toPoint.y, 
                paint
                );
    }
}

将此类添加到项目中(任何包名都可以)并在res / values下为XML参数创建属性文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CoachmarkArrow">
        <attr name="size" format="dimension" />
        <attr name="color" format="color" />
        <attr name="from" format="enum">
            <enum name="topleft" value="0"/>
            <enum name="topright" value="1"/>
            <enum name="bottomleft" value="2"/>
            <enum name="bottomright" value="3"/>
        </attr>
        <attr name="to" format="enum">
            <enum name="topleft" value="0"/>
            <enum name="topright" value="1"/>
            <enum name="bottomleft" value="2"/>
            <enum name="bottomright" value="3"/>
        </attr>
    </declare-styleable>
</resources>

现在您可以像任何其他视图一样在您的coachmarks活动的XML-Layout中创建“needle”,例如

<com.yourpackage.CoachmarkArrow
    xmlns:coachmark="http://schemas.android.com/apk/res/com.yourproject"    
    android:layout_height="100dp"
    android:layout_width="match_parent"
    coachmark:size="3dip"
    coachmark:color="@android:color/white"
    coachmark:from="bottomright"
    coachmark:to="topleft"
/>  

创建一个“针”,其头部位于右下方,尖端位于矩形的左上角,该矩形高100 dp,宽度与包含的父ViewGroup一样宽。

通过这种方式,您可以创建自动适应不同屏幕尺寸的coachmarks。例如,如果使用相对布局,请为要在coachmarks活动中描述的UI元素创建虚拟视图,并告诉相对布局将教练标记放在虚拟视图下方但位于您居中的说明文本框上方在窗口中间。这样,coachmark自动获得正确的大小,从文本框指向UI元素。

希望这有助于某人!

答案 2 :(得分:1)

我试图做类似的事情。我使用Activity制作了消息对话框。对于我在Manifest中写的这个活动:

<activity android:name=".MessDial"
 android:label="@string/lblDialog"
 android:theme="@style/Theme.Transparent">
</activity>

在这项活动的主体中,我对透明度没有任何特别之处。

我希望它会对你有所帮助。

答案 3 :(得分:0)

您可以尝试此示例显示第一次指示屏幕,而不显示任何其他库 如果您只想在第一次显示指令,可以在Preference存储中添加一些标志。可以找到一个示例here

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    SharedPreferences pref= PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    boolean check = pref.getBoolean("firstime", true);
    if(check==true){
        Intent i = new Intent(MainActivity.this, Tutorial_screen.class);//starting activity for the Frist time
        startActivity(i);
    }