Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a tutorial (coach mark) overlay. Need help moving a view based on the position of another

Tags:

android

Hello I am trying to make a coach mark over lay tutorial.

Main.java

public class Main extends Activity {

    private Button button1;
    private int x;

    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_help_overlay);
       button1 = (Button)findViewById(R.id.button1);
       x =  button1.getTop();


                  showOverLay();

    }

    private void showOverLay(){

        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        final Dialog dialog = new Dialog(this, 0);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
        dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);   

        dialog.setContentView(R.layout.overlay_view);

        RelativeLayout layout = (RelativeLayout) dialog.findViewById(R.id.overlayLayout);

        layout.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) 
            {
                Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
                dialog.dismiss();

            }

        });

        dialog.show();

    }
}

So basically, the showOverlay method is called when the activity first starts. It shows a dialog that takes up the whole screen and has a transparent background has no title. overlay.xml seen below is the layout of this dialog.

What I want to do is dynamically adjust the position of the text view so its above the button to compensate for different device screens (in future I will add image views with arrows pointing to things so it would be weird if these arrows don't point at view they refer to).

Please note. I cannot use showCaseView because I will be targeting api 8.

enter image description here

The above image shows what I want to do. Move the text view that says "HEEEEEELP" to be slightly above the button.

main_activity.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="96dp"
        android:onClick="idk"
        android:text="This Button" />
</RelativeLayout>

overlay.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@null"
    android:id="@+id/overlayLayout">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="HEEEEEEELP"
        android:textColor="#FFFFFF"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

Thank you for reading.

Update 2

My OnCreate Method

 @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_help_overlay);
       button1 = (Button)findViewById(R.id.button1);
       button1.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
            public boolean onPreDraw() {
                 top =  button1.getTop();
                 bottom = button1.getBottom();
                 left = button1.getLeft();
                 right = button1.getRight();
                 showOverLay();
                 button1.getViewTreeObserver().removeOnPreDrawListener(this);
                 return true;
            }
        });


    }

I now have access to the co-ordinates of button1. However, I am unsure of how to go about placing the text view above the button which is able to cater for different device sizes. I tried playing around with the parameters of the setMargins method but its hard to judge the amounts. I did some research and found i could use a relative layout with layout params and use fields like ABOVE etc. however this does not seem to be working as intended. The text view does not go above the button.

My code.

RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)textView.getLayoutParams();
lp.addRule(RelativeLayout.CENTER_HORIZONTAL, R.id.button1);
lp.addRule(RelativeLayout.ABOVE, R.id.button1);

textView.setLayoutParams(lp);

Please note that my overlay_view.xml has become a relative layout.

like image 823
user3364963 Avatar asked Feb 02 '26 04:02

user3364963


1 Answers

This is what you should do:

button1.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
    public boolean onPreDraw() {
         button1.getViewTreeObserver().removeOnPreDrawListener(this);
         x =  button1.getTop();
         showOverLay();
         return true;
    }
});

Actually when you call x = button1.getTop(); in onCreate() the Button view is not yet drawn and measured, hence the value of getTop is 0. Try this out.

like image 103
Sagar Waghmare Avatar answered Feb 04 '26 22:02

Sagar Waghmare



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!