Question

am creating an application in which i am using framelayout ..... I have used three class 1) activity 2)selecting image 3)drawing on image

so my activity class is as follow

  public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         i= new FirstImage(this);


         j=(Draw)findViewById(R.id.info);
         t=(TextView)findViewById(R.id.textView);
         k=(TextView)findViewById(R.id.textView1);
         back=(ImageButton)findViewById(R.drawable.monotone_arrow_next_left);
         next=(ImageButton)findViewById(R.drawable.monotone_arrow_next_lrightcopy);
         if (count==0){
             ((FirstImage) i).changeImage(R.drawable.human);

         }
         addListenerOnButton();
    }
    private void addListenerOnButton() {
        // TODO Auto-generated method stub




        next.setOnClickListener( new OnClickListener() {


            @Override
            public void onClick(View arg0) {
                if(count==0){

                    //i.startAnimation(animationFadeout);
                    ((FirstImage) i).changeImage(R.drawable.hand);
                back.setEnabled(true);
                count++;

                addListenerOnButton();

                }
                else if (count==1){
                    //i.startAnimation(animationFadeout);
                    ((FirstImage) i).changeImage(R.drawable.tissue);
                    count++;

                    addListenerOnButton();

                }

                else if (count==2){
                    //i.startAnimation(animationFadeout);
                    ((FirstImage) i).changeImage(R.drawable.cell);
                    count++;

                    addListenerOnButton();


                }
                else if (count==3){
                    //nucleus
                    //i.startAnimation(animationFadeout);
                    ((FirstImage) i).changeImage(R.drawable.nucleus);
                    count++;

                    addListenerOnButton();

                }
                else if (count==4){
                    //nchromosome
                    //i.startAnimation(animationFadeout);
                    ((FirstImage) i).changeImage(R.drawable.chromosome);
                    count++;

                    addListenerOnButton();

                }
                else
                {   //double helix
                    //i.startAnimation(animationFadeout);
                    count++;
                    ((FirstImage) i).changeImage(R.drawable.dnahelix);
                    next.setEnabled(false);

                    addListenerOnButton();

                }

            }
        });

        back.setOnClickListener(new OnClickListener() {


            @Override
            public void onClick(View arg0) {
                if(count==1){
                    //i.startAnimation(animationFadeout);
                    ((FirstImage) i).changeImage(R.drawable.human);
                    back.setEnabled(false);
                    count--;

                    addListenerOnButton();

                    }
                    else if (count==2){
                        //i.startAnimation(animationFadeout);
                        ((FirstImage) i).changeImage(R.drawable.hand);
                        count--;

                        addListenerOnButton();

                    }

                    else if (count==3){
                        //i.startAnimation(animationFadeout);
                        ((FirstImage) i).changeImage(R.drawable.tissue);
                        count--;

                        addListenerOnButton();


                    }
                    else if (count==4){
                        //i.startAnimation(animationFadeout);
                        ((FirstImage) i).changeImage(R.drawable.cell);
                        count--;

                        addListenerOnButton();

                    }
                    else if (count==5){
                        //nucleus
                        //i.startAnimation(animationFadeout);
                        ((FirstImage) i).changeImage(R.drawable.nucleus);
                        count--;

                        addListenerOnButton();


                    }
                    else {
                        //chromosome
                        //count==6
                        //i.startAnimation(animationFadeout);
                        ((FirstImage) i).changeImage(R.drawable.chromosome);
                        count--;

                        addListenerOnButton();
                        next.setEnabled(true);

                    }
                }
            });
    }


}

my class which is selecting an image it is as follow ..

   public class FirstImage extends ImageView implements OnTouchListener {

    ImageView i;
    MotionEvent event;
    int x;
    Bitmap image;
    String huma ="human";
    String info = "";
     float y = 0; //init value 
     float z = 0; //init value
     Animation animationFadeIn;
    Draw child;

    public FirstImage(Context context) { 
        super(context); 
        child=new Draw (context);
        i= new ImageView (context); 


        } 
    public FirstImage(Context context, AttributeSet attrs) { 
        super(context, attrs);
        } 


    public void changeImage(int id){
        final Animation animationFadeout=AnimationUtils.loadAnimation(getContext(), R.anim.zoomout);
                    i.setImageResource(id);
                    i.startAnimation(animationFadeout);
                    i.setOnTouchListener(this);

    }
    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        // TODO Auto-generated method stub
        return false;
    }
    } 

my class which will draw on the image it is as follow

public class Draw extends View {
    String info = "";
    float x = 0;    
    float y = 0;    
    int color = Color.GREEN;    
    public Draw(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
    public Draw(Context context, AttributeSet attrs) {
          super(context, attrs);

    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setColor(color);
        paint.setStrokeWidth(2);
        paint.setTextSize(30);

        canvas.drawLine(x-10, y, x+10, y, paint);
        canvas.drawLine(x, y-10, x, y+10, paint);
        canvas.drawText(info, x, y, paint);

    }

    public void updateInfo(String t_info, float t_x, float t_y){
        info = t_info;
        x = t_x;
        y = t_y;

        invalidate();
    }

    public void clearInfo(){
        info = "";
        x = 0;
        y = 0;
        invalidate();
    }
}

it is showing unexpeteced closing of application ...but in the logcat showing

   05-21 15:55:18.964: E/AndroidRuntime(850): FATAL EXCEPTION: main
05-21 15:55:18.964: E/AndroidRuntime(850): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.nam/com.example.nam.AshActivity}: java.lang.NullPointerException
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.os.Looper.loop(Looper.java:123)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.app.ActivityThread.main(ActivityThread.java:3683)
05-21 15:55:18.964: E/AndroidRuntime(850):  at java.lang.reflect.Method.invokeNative(Native Method)
05-21 15:55:18.964: E/AndroidRuntime(850):  at java.lang.reflect.Method.invoke(Method.java:507)
05-21 15:55:18.964: E/AndroidRuntime(850):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-21 15:55:18.964: E/AndroidRuntime(850):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-21 15:55:18.964: E/AndroidRuntime(850):  at dalvik.system.NativeStart.main(Native Method)
05-21 15:55:18.964: E/AndroidRuntime(850): Caused by: java.lang.NullPointerException
05-21 15:55:18.964: E/AndroidRuntime(850):  at com.example.nam.AshActivity.addListenerOnButton(AshActivity.java:48)
05-21 15:55:18.964: E/AndroidRuntime(850):  at com.example.nam.AshActivity.onCreate(AshActivity.java:40)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-21 15:55:18.964: E/AndroidRuntime(850):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
05-21 15:55:18.964: E/AndroidRuntime(850):  ... 11 more

my xml file is as follow ....

<?xml version="1.0" encoding="utf-8"?>

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


  <!--  Screen Design for VIDEOS -->
<TableLayout 
    android:id="@+id/tablelayout"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:stretchColumns="1">

     <TableRow
          android:id="@+id/tableRow1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" >

          <TextView
               android:id="@+id/textView"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:padding="15dip"
              android:text="pic on click which will tell where is the dna located in human body or cell "
              android:textSize="18dip" />
      </TableRow>


      <TableRow
          android:id="@+id/tableRow2"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" >
    <FrameLayout
        android:layout_width="wrap_content"
          android:layout_height="wrap_content" >
         <com.example.nam.FirstImage
             android:id="@+id/image"
             android:layout_height="wrap_content" 
             android:layout_width="fill_parent" />
          <com.example.nam.Draw
             android:id="@+id/info"
             android:layout_height="wrap_content" 
             android:layout_width="fill_parent" />

      </FrameLayout>   
      </TableRow>

      <TableRow
          android:id="@+id/tableRow3"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" >

          <LinearLayout
              android:id="@+id/linearLayout1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" >

              <ImageView
                  android:id="@+id/button1"
                  android:layout_width="100dp"
                  android:layout_height="wrap_content"
                  android:src="@drawable/monotone_arrow_next_left"/>
              <ImageView
                  android:id="@+id/button2"
                  android:layout_width="100dp"
                  android:layout_height="wrap_content"
                 android:src="@drawable/monotone_arrow_next_lrightcopy"/>

          </LinearLayout>

      </TableRow>
       <TableRow
          android:id="@+id/tableRow4"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" >
          <TextView
              android:id="@+id/textView1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:padding="15dip"
              android:text="please don't mind  "
              android:textSize="18dip" />
          </TableRow>

  </TableLayout>
  </ScrollView>
Was it helpful?

Solution

The error points to a row when you are using a custom view: com.example.nam.FirstImage.

When using your own View extensions in an xml layout, you should declare a namespace to them.

What you are missing is a line:

xmlns:name="http://schemas.android.com/apk/res/com.example.nam"

so your layout's root element should look like this:

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

Edit1: Now the NullPointerException is inside your FirstImage class.

There you have a variable named event of type MotionEvent, which is nowhere initialized, but you use it inside your changeImage method:

i.onTouchEvent(event);

This must throw the NPE. Since you call that method from onCreate, you cannot assign to it a valid MotionEvent, this way you need either

  • to make up one, or
  • check if the event member is null, and only call the onTouchEvent if it is not null!

Eidt2: ...after comments / chat, here is what you should do:

  • remove the i.onTouchEvent(event); from your changeImage method;
  • implement properly the onTouch method to show the desired text.
  • remove the ImageView instance, and use this instead.

This way your FirstImage class should change:

public class FirstImage extends ImageView implements OnTouchListener
{
    MotionEvent event;
    int x;
    Bitmap image;
    String huma = "human";
    String info = "";
    float y = 0; // init value
    float z = 0; // init value
    Animation animationFadeIn;
    Draw child;

    public FirstImage(Context context)
    {
        super(context);
        child = new Draw(context);
    }

    public FirstImage(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public void changeImage(int id)
    {
        final Animation animationFadeout = AnimationUtils.loadAnimation(
                getContext(), R.anim.zoomout);
        this.setImageResource(id);
        this.startAnimation(animationFadeout);
        this.setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1)
    {
    //  TODO: Here you show the text you want, e.g.:
    //  final TextView tv = (TextView)findViewById(R.id.text);
    //  tv.setText("This image is about...");
        return true;
    }
}

Edit3: If you would simplify / clarify a bit your addClickListener method, that would be nice too.

You really don't need to add the listeners to those buttons over and over again...

private void addListenerOnButton()
{
    next.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View arg0)
        {
            switch (count)
            {
                case 0:
                    ((FirstImage) i).changeImage(R.drawable.hand);
                    back.setEnabled(true);
                    break;
                case 1:
                    ((FirstImage) i).changeImage(R.drawable.tissue);
                    break;
                case 2:
                    ((FirstImage) i).changeImage(R.drawable.cell);
                    break;
                case 3:
                    ((FirstImage) i).changeImage(R.drawable.nucleus);
                    break;
                case 4:
                    ((FirstImage) i).changeImage(R.drawable.chromosome);
                    break;
                case 5:
                    ((FirstImage) i).changeImage(R.drawable.dnahelix);
                    next.setEnabled(false);
                    break;
                default:
                    break;
            }
            count++;
        }
    });

    back.setOnClickListener(new OnClickListener()
    {

        @Override
        public void onClick(View arg0)
        {
            switch (count)
            {
                case 1:
                    ((FirstImage) i).changeImage(R.drawable.human);
                    back.setEnabled(false);
                    break;
                case 2:
                    ((FirstImage) i).changeImage(R.drawable.hand);
                    break;
                case 3:
                    ((FirstImage) i).changeImage(R.drawable.tissue);
                    break;
                case 4:
                    ((FirstImage) i).changeImage(R.drawable.cell);
                    break;
                case 5:
                    ((FirstImage) i).changeImage(R.drawable.nucleus);
                    break;
                case 6:
                    ((FirstImage) i).changeImage(R.drawable.chromosome);
                    next.setEnabled(true);
                    break;
                default:
                    break;
            }
            count--;
        }
    });
}

Edit4: Also, please correct your layout xml file, and instead of having ImageViews declared for button1 and button2, use ImageButtons as you try to cast them in the onCreate method anyway:

<ImageButton
    android:id="@+id/button1"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:src="@drawable/monotone_arrow_next_left"/>
<ImageButton
    android:id="@+id/button2"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:src="@drawable/monotone_arrow_next_lrightcopy"/>

and the assignment is done by the button's @id attribute, not by the drawable you have on them!

back = (ImageButton) findViewById(R.id.button1);
next = (ImageButton) findViewById(R.id.button2);

OTHER TIPS

Check this from official documentation about FrameLayout :

FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other. You can, however, add multiple children to a FrameLayout and control their position within the FrameLayout by assigning gravity to each child, using the android:layout_gravity attribute.

If I was you I would try to use two different FrameLayouts to see if it will work..but as I can see from your stacktrace the problem is in your xml file.

EDIT :

So here is the code which is working. Put this on your Activity :

public class AshActivity extends Activity implements OnTouchListener {
ImageView i;
Draw j;
TextView t,k;
ImageView back;
ImageView next;
int count=0;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
     i= new FirstImage(this);
     if (count==0)
         ((FirstImage) i).changeImage(R.drawable.ic_launcher);
     j=(Draw)findViewById(R.id.info);
     t=(TextView)findViewById(R.id.textView);
     k=(TextView)findViewById(R.id.textView1);
     back=(ImageView)findViewById(R.id.button1);
     next=(ImageView)findViewById(R.id.button2);
     addListenerOnButton();

} }

And that should do the trick! : )

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top