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 id
s 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 editText
s 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)
There are several problems with the code used:
this should be something
textVar.setId(id++);
where id is a global variable
I simplified your solution and made it working, you can use it as a base and add your image in between:
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.