How do I get an editText to appear below my image, each time I take a picture?

165 views Asked by At

I'm making a notepad type of app in which the user can take and place pictures in between the text as he is typing it.

In my app I have a button , editText and imageView. When it starts, there is only the button and an editText. The user types into the editText and when he presses the button, the camera opens. The taken picture gets placed right under the editText (under the last line entered by the user). Under the picture a new editText appears and the user can enter text into this. When he presses the button again another picture gets taken, placed below the second editText and a third editText is available to the user to enter text.

So each time the user takes a picture by pressing the button, a new editText appears under the image. This keeps looping, allowing the user to enter both text and images, as many images and paragraphs as he wants.

But this isn't happening. I'm only able to enter text once and take 1 picture. No second editText ever appears. What's going wrong here.

The code for alternating editText and imageView is located in onActivityResult()

mainActivity.java

package com.example.nirvan.cameraexample3;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.Image;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity
{


ImageView myImage;
EditText textVar;
int flag=0;             //flag==0 means place img below text, ==1 means below textVar

private String pictureImagePath = "";
Uri outputFileUri;
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button imgButton=(Button) findViewById(R.id.imgButton);


    View.OnClickListener imgButtonClickListener=new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            String imageFileName = timeStamp + ".jpg";
            File storageDir = Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES);
            pictureImagePath = storageDir.getAbsolutePath() + "/" + imageFileName;
            File file = new File(pictureImagePath);
            outputFileUri = Uri.fromFile(file);
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            startActivityForResult(cameraIntent, 1);
        }
    };
    imgButton.setOnClickListener(imgButtonClickListener);


}



protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    Log.d("TAG","CUSTOOOM");
    RelativeLayout relativeLayout=(RelativeLayout) findViewById(R.id.relativeLayout);
    myImage=new ImageView(this);
    myImage.setId(+1);




    if (requestCode == 1 && resultCode == RESULT_OK)
    {
        File imgFile = new File(pictureImagePath);
       if (imgFile.exists())
        {
            Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
           // myImage = (ImageView) findViewById(R.id.imageViewTest);

            //this code ensures the imageView is placed below the editText
            RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams
                    (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);

            if(flag==0)
               {
                   relativeParams.addRule(RelativeLayout.BELOW, R.id.text);
                   flag=1;
               }
            else if(flag==1)
                relativeParams.addRule(RelativeLayout.BELOW, textVar.getId());

            //myImage.setLayoutParams(relativeParams);
            relativeLayout.addView(myImage,relativeParams);
            //
            myImage.setImageBitmap(myBitmap);


            //place the new editText below the imgaeView just placed
            relativeParams = new RelativeLayout.LayoutParams
                    (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            relativeParams.addRule(RelativeLayout.BELOW, myImage.getId());
            textVar=new EditText(this);
            textVar.setId(+2    );
            relativeLayout.addView(textVar,relativeParams);
            textVar.setText("NEW");

        }
    }//






}



}

mainActivity.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:id="@+id/relativeLayout"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.nirvan.cameraexample3.MainActivity">





<Button
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="IMG"
    android:id="@+id/imgButton"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" />

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/text"
    android:layout_below="@id/imgButton"
    />

</RelativeLayout>

UPDATE- Taking Petrumo's suggestions I have revised the code. Although it's still not working the way it should. After taking the first image, a second editText is not being displayed under the image. I have made sure that the ids for the textView and imageView are different for each iteration of the method.

onActivityResult() updated

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    Log.d("TAG","CUSTOOOM");
    RelativeLayout relativeLayout=(RelativeLayout) findViewById(R.id.relativeLayout);
    myImage=new ImageView(this);
    myImage.setId(id1++);
    textVar.setId(id2++);




    if (requestCode == 1 && resultCode == RESULT_OK)
    {
        File imgFile = new File(pictureImagePath);
       if (imgFile.exists())
        {
            Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
           // myImage = (ImageView) findViewById(R.id.imageViewTest);

            //this code ensures the imageView is placed below the editText
            RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams
                    (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);

            if(flag==0)
               {
                   relativeParams.addRule(RelativeLayout.BELOW, R.id.text);
                   flag=1;
               }
            else if(flag==1)
                relativeParams.addRule(RelativeLayout.BELOW, textVar.getId());




            //myImage.setLayoutParams(relativeParams);
            relativeLayout.addView(myImage,relativeParams);
            //
            myImage.setImageBitmap(myBitmap);


            //place the new editText below the imgaeView just placed
            relativeParams = new RelativeLayout.LayoutParams
                    (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            relativeParams.addRule(RelativeLayout.BELOW, myImage.getId());
            textVar=new EditText(this);
            //textVar.setId(id2++);

            relativeLayout.addView(textVar,relativeParams);
            textVar.setText("NEW");

        }
    }//






}

UPDATE2: So I simply replaced my code inside onActivityResult with Petrumo's ..and it works. The editTexts appear one below the other. But when I insert the imageView code , the app crashes right after taking the picture.

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    RelativeLayout relativeLayout=(RelativeLayout) findViewById(R.id.relativeLayout);
    RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams
            (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    if(textVar != null)
    {
        relativeParams.addRule(RelativeLayout.BELOW, textVar.getId());
    }
    else
    {
        relativeParams.addRule(RelativeLayout.BELOW, R.id.text);
    }

    myImage=new ImageView(this);
    myImage.setId(id1++);
    //set image

        File imgFile = new File(pictureImagePath);
        if (imgFile.exists() && requestCode == 1 && resultCode == RESULT_OK)
        {
            Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
            relativeLayout.addView(myImage, relativeParams);
            myImage.setImageBitmap(myBitmap);


        }

    //



    textVar=new EditText(MainActivity.this);
    textVar.setId(id2++);
    relativeParams.addRule(RelativeLayout.BELOW, myImage.getId());
    relativeLayout.addView(textVar, relativeParams);
    textVar.setText("NEW");
    relativeLayout.addView(textVar, relativeParams);




}

Log

 FATAL EXCEPTION: main
                                                                               Process: com.example.nirvan.cameraexample3, PID: 27598
                                                                               java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.example.nirvan.cameraexample3/com.example.nirvan.cameraexample3.MainActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
                                                                                   at android.app.ActivityThread.deliverResults(ActivityThread.java:3432)
                                                                                   at android.app.ActivityThread.handleSendResult(ActivityThread.java:3475)
                                                                                   at android.app.ActivityThread.access$1300(ActivityThread.java:139)
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                   at android.os.Looper.loop(Looper.java:136)
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5086)
                                                                                   at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                   at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                                                                                   at dalvik.system.NativeStart.main(Native Method)
                                                                                Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
                                                                                   at android.view.ViewGroup.addViewInner(ViewGroup.java:3564)
                                                                                   at android.view.ViewGroup.addView(ViewGroup.java:3417)
                                                                                   at android.view.ViewGroup.addView(ViewGroup.java:3393)
                                                                                   at com.example.nirvan.cameraexample3.MainActivity.onActivityResult(MainActivity.java:105)
                                                                                   at android.app.Activity.dispatchActivityResult(Activity.java:5446)
                                                                                   at android.app.ActivityThread.deliverResults(ActivityThread.java:3428)
                                                                                   at android.app.ActivityThread.handleSendResult(ActivityThread.java:3475) 
                                                                                   at android.app.ActivityThread.access$1300(ActivityThread.java:139) 
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258) 
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                   at android.os.Looper.loop(Looper.java:136) 
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5086) 
                                                                                   at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                       at java.lang.reflect.Method.invoke(Method.java:515)
1

There are 1 answers

5
petrumo On

There are several problems with the code used:

  • using of the same id textVar.setId(+2 );

this should be something

textVar.setId(id++);

where id is a global variable

  • the same needs to be applied to the image id, it needs to be unique and used by the next one if you want to place it bellow

I simplified your solution and made it working, you can use it as a base and add your image in between:

RelativeLayout relativeLayout=(RelativeLayout) findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams
 (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
  if(textVar != null)
  {
    relativeParams.addRule(RelativeLayout.BELOW, textVar.getId());
  } else {
    relativeParams.addRule(RelativeLayout.BELOW, R.id.text);
  }

  textVar=new EditText(MainActivity.this);
  textVar.setId(id++);
  textVar.setText("NEW");


 relativeLayout.addView(textVar, relativeParams);

A simpler way, if you only want to add them below is to use LinearLayout with orientation vertical, or a more elegant solution to change it to a list with adapter as suggested in the comment.