'Scrolling a RulerView programatically in other Class does not work, object id returns null

I am developing an app that uses a transparent section to show one piece of information, in this case a ruler that slides by touching with finger. I found something similar in this site: https://github.com/MiHomes/RuleView (thanks to the author) It has a class RulerView which is an adaptation of View and Scrollview, it has a transparent window and it slides and draws the numbers inside it. It works perfectly, the rule animates when you slide your finger on it.

public class RulerView extends View {
    private Context mContext;
    private Paint centerLinePaint;  
    private Paint grayLinePaint;    
    private Paint txtPaint;         
    private Paint currentTextPaint; 

    private int space = 50;
    private int startValue = 1900;
    private int endValue = 2018;
    private int width;
    private int height;
    private float mLastX;
    private int touchSlop;
    private Scroller mScroller;
    private int mMinimumVelocity;
    ...
    ...
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = startValue ; i < endValue  + 1; i++) {
            int lineHeight = 50;
            if (i % interval == 0) {
                lineHeight = 80;
                int x = (i - startValue ) * space;
                if (x > 0 || x < width) {
                    canvas.drawText(String.valueOf(i ), x-textOffset, lineHeight + 50, txtPaint);
                }
            }
    ...

And in the main class the ruler is created if you want to initialize its values such as max/min values.

public class MainActivity extends Activity {

    private TextView tvhorizontal;
    private RulerView horizontalRullView;
    private VerticalRulerView verticalRullView;
    private TextView tVertical;

    int       valor = 50;
    RulerView regla, regla2;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initRuleView();
        initVerticalRuleView();
        
        // ** NONE OF THESE WORKS **
regla  = new RulerView(this);   
        regla2 = (RulerView)findViewById(R.id.rulerView_horizontal);
        regla2.setNumber(295);

...
    //Add a layout that contains some Buttons and the RulerView:
controlInflater = LayoutInflater.from(getBaseContext() );
    View viewControl = controlInflater.inflate(R.layout.layout_controles, null);;
    LayoutParams layoutParamsControl =
    new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    this.addContentView(viewControl, layoutParamsControl);

    }//onCreate

I needed to animate it programatically from another class, which I achieved it by sending a Touch Event from the main class when I press a button for example.

// dispatch the event
event = MotionEvent.obtain(downTime, eventTime, action, x, y, metaState);
regla2.dispatchTouchEvent(event);

This test works perfectly, Now I want to do the same in the real App which has a Camera Preview and a View with a Canvas, and a layer of buttons for some controls, so I added the RulerView which does works by touching it with the finger, like the original app, but it doesn’t work programatically (I want to control it with the values of the sensor in a Drawing class that inherites from View). I receive a Null Pointer error message due to findViewById returns Null for the id of the Ruler. This is the structure of the new App:

Main class check wether the device has camera and/or flash and some sensors

public class Activity_Main_Camera extends Activity
{
    private Camera camera;                *** To use Camera
    private Camera_Preview cameraPreview; ***
    
    int  hasCamara = 0, hasFlash = 0; 
    int  flashOn =  -1;
    int  hasAcel =   0, hasMagnetic = 0;
       ...
    if (cameraAvailable(camera)) //Can it be used?
    {   initCameraPreview();
            if (angle_Ini_0 == 90) camera.setDisplayOrientation(angle_Ini_0);
    public Camera getCameraInstance() 
    {   Camera c = null;
        try {
            c = Camera.open();
        } catch (Exception e) {
            Log.d("getCamera failed", e.toString());//Camera not available or not exists
        }
        return c;
    }
  ...

There is a class that uses a Canvas to draw images, and reads sensor events

public class Drawings extends View implements SensorEventListener
{
    Context  contexto;
    int      orientInicial = -5;
    int      angle_Ini_0   = -5;

    protected void onDraw(final Canvas canvas)
    {   canvas.drawLine(0,alto/2,   ancho,alto/2,  pincelEjes);
        canvas.drawLine(ancho/2,0,  ancho/2,alto,  pincelEjes);

        int bajar = 0; //aux
        int x1,y1,x2,y2;
        
        canvas.save();
            //IF VERTICAL --> Solved in Main
            //canva.rotate(inclinacion+90, ancho/2, alto/2);
            //imgProtractor.setBounds(0,alto/2-ancho/2, ancho,alto/2+ancho/2);

            //IF LANDSCAPE --> solved in Main
            canvas.rotate(anguloRoll, ancho/2, alto/2);
         ...
       canvas.restore();

But when I want to use the Rulers in this App, it returns a null object

private void initSensors()
    {   
sm = (SensorManager)contexto.getSystemService(Context.SENSOR_SERVICE);
        sensorAcel = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorMag  = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        if (sensorAcel!=null) hasAcel     = 1;
        if (sensorMag !=null) hasMagnetic = 1;

<bold>// ** NONE OF THESE WORKS **</bold>
        regla =(RulerView)findViewById(R.id.rulerView_horizontal); //**THIS RETURNS NULL AND CRASHES IF I USE regla **        
        regla2= new RulerView(contexto); //** regla2 DOES NOT WORK ALTHOUGH DOES´NT CRASH **
        System.out.println("regla=" + regla); // ** regla is NULL **
        
    }//initSensors

public void onSensorChanged()
{
    if (regla!=null)
    {    regla.scrollBy( 50, 0 ); <bold>// ** Does not work because regla is null **</bold>
         ...
    }
}

The activity_main_camera.xml layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.app.subapp.Camera_Preview
        android:id="@+id/camera_preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="98dp"
        android:layout_marginBottom="54dp"
        android:onClick="mostrarVistas"
        android:padding="3dp"
        android:text="Mostrar Grafica"
        android:visibility="invisible" />
    ...
</RelativeLayout>

The layout_control.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_control"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView5"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="10"
        android:text="TextView" />

    <com.app.appprotractor.RulerView
        android:id="@+id/rulerView_horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
    ...
    ...

</LinearLayout>

What should I do to fix this problem?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source