title: Placing custom views in Layout in Android
body: <p>I'm developing different classes and defining objects from these classes 
  and for each object there are some functions that I'm calling when a button is pressed or the screen is touched </p>
  
  <p>I want to place my objects as in the picture in <a href="http://developer.android.com/guide/topics/ui/layout/relative.html" rel="nofollow noreferrer">this link</a></p>
  
  <p>When I place these objects using the following way, I can not call the functions of each class </p>
  
  <p>this is the code I'm using I took it from <a href="https://stackoverflow.com/questions/3205191/android-and-mjpeg/3305276#3305276">Android and MJPEG</a></p>
  
  <p>This the <strong>main activity</strong></p>
  
  <pre><code>package de.mjpegsample;
  import android.app.Activity;
  import android.os.Bundle;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.Window;
  import android.view.WindowManager;
  import de.mjpegsample.MjpegView.MjpegInputStream;
  import de.mjpegsample.MjpegView.MjpegView;
  
  public class MjpegSample extends Activity {
  
  private MjpegView mv;
  private MjpegView mv2;
  
  private static final int MENU_QUIT = 1;
  
  
  public void onCreate(Bundle icicle) {
      super.onCreate(icicle);
      setContentView(R.layout.activity_main);
      //sample public cam
      String URL = "http://gamic.dnsalias.net:7001/img/video.mjpeg";
      mv = (MjpegView)findViewById(R.id.mjpegView1);
      mv2 = (MjpegView)findViewById(R.id.mjpegView2);
  
  }
  
  @Override
  protected void onResume() {
      super.onResume();
  
  
      mv.init(this);
      mv2.init(this);
  
     }
  
   public void onPause() {
      super.onPause();
      mv.stopPlayback();
   }
   }
  </code></pre>
  
  <p><strong>MjpegView Class</strong></p>
  
  <pre><code>package de.mjpegsample.MjpegView;
  
  import java.io.IOException;
  import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Paint;
  import android.graphics.PorterDuff;
  import android.graphics.PorterDuffXfermode;
  import android.graphics.Rect;
  import android.graphics.Typeface;
  import android.util.AttributeSet;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  
  public class MjpegView extends SurfaceView implements SurfaceHolder.Callback {
  public final static int POSITION_UPPER_LEFT  = 9;
  public final static int POSITION_UPPER_RIGHT = 3;
  public final static int POSITION_LOWER_LEFT  = 12;
  public final static int POSITION_LOWER_RIGHT = 6;
  
  public final static int SIZE_STANDARD   = 1; 
  public final static int SIZE_BEST_FIT   = 4;
  public final static int SIZE_FULLSCREEN = 8;
  
  private MjpegViewThread thread;
  private MjpegInputStream mIn = null;    
  private boolean showFps = false;
  private boolean mRun = false;
  private boolean surfaceDone = false;    
  private Paint overlayPaint;
  private int overlayTextColor;
  private int overlayBackgroundColor;
  private int ovlPos;
  private int dispWidth;
  private int dispHeight;
  private int displayMode;
  
  public class MjpegViewThread extends Thread {
  private SurfaceHolder mSurfaceHolder;
  private int frameCounter = 0;
  private long start;
  private Bitmap ovl;
  
      public MjpegViewThread(SurfaceHolder surfaceHolder, Context context) { mSurfaceHolder = surfaceHolder; }
  
      private Rect destRect(int bmw, int bmh) {
          int tempx;
          int tempy;
          if (displayMode == MjpegView.SIZE_STANDARD) {
              tempx = (dispWidth / 2) - (bmw / 2);
              tempy = (dispHeight / 2) - (bmh / 2);
              return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
          }
          if (displayMode == MjpegView.SIZE_BEST_FIT) {
              float bmasp = (float) bmw / (float) bmh;
              bmw = dispWidth;
              bmh = (int) (dispWidth / bmasp);
              if (bmh &gt; dispHeight) {
                  bmh = dispHeight;
                  bmw = (int) (dispHeight * bmasp);
              }
              tempx = (dispWidth / 2) - (bmw / 2);
              tempy = (dispHeight / 2) - (bmh / 2);
              return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
          }
          if (displayMode == MjpegView.SIZE_FULLSCREEN) return new Rect(0, 0, dispWidth, dispHeight);
          return null;
      }
  
      public void setSurfaceSize(int width, int height) {
          synchronized(mSurfaceHolder) {
              dispWidth = width;
              dispHeight = height;
          }
      }
  
      private Bitmap makeFpsOverlay(Paint p, String text) {
          Rect b = new Rect();
          p.getTextBounds(text, 0, text.length(), b);
          int bwidth  = b.width()+2;
          int bheight = b.height()+2;
          Bitmap bm = Bitmap.createBitmap(bwidth, bheight, Bitmap.Config.ARGB_8888);
          Canvas c = new Canvas(bm);
          p.setColor(overlayBackgroundColor);
          c.drawRect(0, 0, bwidth, bheight, p);
          p.setColor(overlayTextColor);
          c.drawText(text, -b.left+1, (bheight/2)-((p.ascent()+p.descent())/2)+1, p);
          return bm;           
      }
  
      public void run() {
          start = System.currentTimeMillis();
          PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
          Bitmap bm;
          int width;
          int height;
          Rect destRect;
          Canvas c = null;
          Paint p = new Paint();
          String fps = "";
          while (mRun) {
              if(surfaceDone) {
                  try {
                      c = mSurfaceHolder.lockCanvas();
                      synchronized (mSurfaceHolder) {
                          try {
                              bm = mIn.readMjpegFrame();
                              destRect = destRect(bm.getWidth(),bm.getHeight());
                              c.drawColor(Color.BLACK);
                              c.drawBitmap(bm, null, destRect, p);
                              if(showFps) {
                                  p.setXfermode(mode);
                                  if(ovl != null) {
                                      height = ((ovlPos &amp; 1) == 1) ? destRect.top : destRect.bottom-ovl.getHeight();
                                      width  = ((ovlPos &amp; 8) == 8) ? destRect.left : destRect.right -ovl.getWidth();
                                      c.drawBitmap(ovl, width, height, null);
                                  }
                                  p.setXfermode(null);
                                  frameCounter++;
                                  if((System.currentTimeMillis() - start) &gt;= 1000) {
                                      fps = String.valueOf(frameCounter)+"fps";
                                      frameCounter = 0; 
                                      start = System.currentTimeMillis();
                                      ovl = makeFpsOverlay(overlayPaint, fps);
                                  }
                              }
                          } catch (IOException e) {}
                      }
                  } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); }
              }
          }
      }
  }
  
  private void init(Context context) {
      SurfaceHolder holder = getHolder();
      holder.addCallback(this);
      thread = new MjpegViewThread(holder, context);
      setFocusable(true);
      overlayPaint = new Paint();
      overlayPaint.setTextAlign(Paint.Align.LEFT);
      overlayPaint.setTextSize(12);
      overlayPaint.setTypeface(Typeface.DEFAULT);
      overlayTextColor = Color.WHITE;
      overlayBackgroundColor = Color.BLACK;
      ovlPos = MjpegView.POSITION_LOWER_RIGHT;
      displayMode = MjpegView.SIZE_STANDARD;
      dispWidth = getWidth();
      dispHeight = getHeight();
  }
  
  public void startPlayback() { 
      if(mIn != null) {
          mRun = true;
          thread.start();         
      }
  }
  
  public void stopPlayback() { 
      mRun = false;
      boolean retry = true;
      while(retry) {
          try {
              thread.join();
              retry = false;
          } catch (InterruptedException e) {}
      }
  }
  
  public MjpegView(Context context, AttributeSet attrs) { super(context, attrs); init(context); }
  public void surfaceChanged(SurfaceHolder holder, int f, int w, int h) { thread.setSurfaceSize(w, h); }
  
  public void surfaceDestroyed(SurfaceHolder holder) { 
      surfaceDone = false; 
      stopPlayback(); 
  }
  
  public MjpegView(Context context) { 
      super(context); 
      init(context); 
      }    
  public void surfaceCreated(SurfaceHolder holder) { 
      surfaceDone = true; 
      }
  public void showFps(boolean b) { 
      showFps = b; 
      }
  public void setSource(MjpegInputStream source) { 
      mIn = source; 
      startPlayback();
      }
  public void setOverlayPaint(Paint p) { 
      overlayPaint = p; 
      }
  public void setOverlayTextColor(int c) { 
      overlayTextColor = c; 
      }
  public void setOverlayBackgroundColor(int c) { 
      overlayBackgroundColor = c; 
      }
  public void setOverlayPosition(int p) { 
      ovlPos = p; 
      }
  public void setDisplayMode(int s) { 
      displayMode = s; 
      }
      }
  </code></pre>
  
  <p><strong>MjpegInputStream Class</strong></p>
  
  <pre><code>package de.mjpegsample.MjpegView;
  
  import java.io.BufferedInputStream;
  import java.io.ByteArrayInputStream;
  import java.io.DataInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URI;
  import java.util.Properties;
  
  import org.apache.http.HttpResponse;
  import org.apache.http.client.ClientProtocolException;
  import org.apache.http.client.methods.HttpGet;
  import org.apache.http.impl.client.DefaultHttpClient;
  
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  
  public class MjpegInputStream extends DataInputStream {
  private final byte[] SOI_MARKER = { (byte) 0xFF, (byte) 0xD8 };
  private final byte[] EOF_MARKER = { (byte) 0xFF, (byte) 0xD9 };
  private final String CONTENT_LENGTH = "Content-Length";
  private final static int HEADER_MAX_LENGTH = 100;
  private final static int FRAME_MAX_LENGTH = 40000 + HEADER_MAX_LENGTH;
  private int mContentLength = -1;
  
  public static MjpegInputStream read(String url) {
      HttpResponse res;
      DefaultHttpClient httpclient = new DefaultHttpClient();     
      try {
          res = httpclient.execute(new HttpGet(URI.create(url)));
          return new MjpegInputStream(res.getEntity().getContent());              
      } catch (ClientProtocolException e) {
      } catch (IOException e) {}
      return null;
  }
  
  public MjpegInputStream(InputStream in) { super(new BufferedInputStream(in, FRAME_MAX_LENGTH)); }
  
  private int getEndOfSeqeunce(DataInputStream in, byte[] sequence) throws IOException {
      int seqIndex = 0;
      byte c;
      for(int i=0; i &lt; FRAME_MAX_LENGTH; i++) {
          c = (byte) in.readUnsignedByte();
          if(c == sequence[seqIndex]) {
              seqIndex++;
              if(seqIndex == sequence.length) return i + 1;
          } else seqIndex = 0;
      }
      return -1;
  }
  
  private int getStartOfSequence(DataInputStream in, byte[] sequence) throws IOException {
      int end = getEndOfSeqeunce(in, sequence);
      return (end &lt; 0) ? (-1) : (end - sequence.length);
  }
  
  private int parseContentLength(byte[] headerBytes) throws IOException, NumberFormatException {
      ByteArrayInputStream headerIn = new ByteArrayInputStream(headerBytes);
      Properties props = new Properties();
      props.load(headerIn);
      return Integer.parseInt(props.getProperty(CONTENT_LENGTH));
  }   
  
  public Bitmap readMjpegFrame() throws IOException {
      mark(FRAME_MAX_LENGTH);
      int headerLen = getStartOfSequence(this, SOI_MARKER);
      reset();
      byte[] header = new byte[headerLen];
      readFully(header);
      try {
          mContentLength = parseContentLength(header);
      } catch (NumberFormatException nfe) { 
          mContentLength = getEndOfSeqeunce(this, EOF_MARKER); 
      }
      reset();
      byte[] frameData = new byte[mContentLength];
      skipBytes(headerLen);
      readFully(frameData);
      return BitmapFactory.decodeStream(new ByteArrayInputStream(frameData));
  }
  }
  </code></pre>
  
  <p>so what I want to do now is to add two objects so I get two squares for streaming
  and I want to add a button if the user click then it displays the information of the streamed path </p>
  
  <p>Here is my xlm file</p>
  
  <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" &gt;
  
  &lt;LinearLayout
      android:id="@+id/r1"
      android:layout_width="fill_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:orientation="horizontal" &gt;
  
      &lt;Button
          android:id="@+id/button1"
          android:layout_width="0dp"
          android:layout_height="match_parent"
          android:layout_weight="1"
          android:text="Button" /&gt;
  
      &lt;de.mjpegsample.MjpegView
          android:id="@+id/mjpegView1"
          android:layout_width="0dp"
          android:layout_height="match_parent"
          android:layout_weight="1" &gt;
  
  &lt;/LinearLayout&gt;
  
  &lt;LinearLayout
      android:id="@+id/r2"
      android:layout_width="fill_parent"
      android:layout_height="0dp"
      android:layout_weight="1" &gt;
  
          &lt;de.mjpegsample.MjpegView
          android:id="@+id/mjpegView2"
          android:layout_width="0dp"
          android:layout_height="match_parent"
          android:layout_weight="1" &gt;
  
     &lt;/LinearLayout&gt;
   &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>another thing is want to add some functions that will get executed when the user touch the screen of the streaming, but I'm still figuring out how can I do this</p>
  
  <p>Now my question is there another way to place my objects on my layout other than the way I'm using, I mean can I define my objects as 
  <code>MyClass obj1 = new MyClass(this);</code> this way I can call the functions without a problem</p>
  
  <p>or if there is another way to fix this</p>
  
  <p>here is the error message from logcat</p>
  
  <pre><code>11-20 11:06:32.732: E/AndroidRuntime(5620): FATAL EXCEPTION: main
  11-20 11:06:32.732: E/AndroidRuntime(5620): java.lang.RuntimeException: Unable to resume activity {com.example.firstapp/com.example.firstapp.MainActivity}: java.lang.NullPointerException
  
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2790)
  
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2819)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2266)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.os.Handler.dispatchMessage(Handler.java:99)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.os.Looper.loop(Looper.java:137)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.ActivityThread.main(ActivityThread.java:5103)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at java.lang.reflect.Method.invokeNative(Native Method)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at java.lang.reflect.Method.invoke(Method.java:525)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at dalvik.system.NativeStart.main(Native Method)
  11-20 11:06:32.732: E/AndroidRuntime(5620): Caused by: java.lang.NullPointerException
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at com.example.firstapp.MainActivity.onResume(MainActivity.java:137)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.Activity.performResume(Activity.java:5211)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2780)
  11-20 11:06:32.732: E/AndroidRuntime(5620):     ... 12 more
  </code></pre>
  
  <p>I tried doing this just to test if it is going to work and same thing happened the application crashed</p>
  
  <pre><code> FrameLayout f1;
   f1 = (FrameLayout)findViewById(R.id.frame1);
   TextView t = new TextView(getApplicationContext());
   t.setText("Hello world");
   f1.addView(t); 
  </code></pre>
  
  <p>but when I tried this it worked</p>
  
  <pre><code> FrameLayout f1 = new FrameLayout(this); 
   TextView t = new TextView(getApplicationContext());
   t.setText("Hello world");
   f1.addView(t); 
  </code></pre>