【发布时间】:2017-01-03 14:42:58
【问题描述】:
我正在制作一个记事本类型的应用程序,用户可以在其中在输入文本时拍摄和放置图片。
在我的应用程序中,我有一个 button、editText 和 imageView。启动时,只有button 和editText。用户输入editText,当他按下button时,相机打开。拍摄的照片被放置在editText 的正下方(在用户输入的最后一行下方)。图片下方会出现一个新的editText,用户可以在其中输入文字。当他再次按下按钮时,另一张照片被拍摄,位于第二张editText 下方,第三张editText 可供用户输入文本。
因此,每次用户按下按钮拍照时,图像下方都会出现一个新的editText。这会一直循环,允许用户输入文本和图像,任意数量的图像和段落。
但这并没有发生。我只能输入一次文字并拍一张照片。没有第二个editText 出现。这里出了什么问题。
editText和imageView交替的代码位于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- 根据 Petrumo 的建议,我已经修改了代码。尽管它仍然没有按应有的方式工作。拍摄第一张图像后,图像下方未显示第二张editText。
我已确保 textView 和 imageView 的 ids 对于方法的每次迭代都不同。
onActivityResult() 已更新
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: 所以我简单地将onActivityResult 中的代码替换为Petrumo 的.. 并且它可以工作。 editTexts 出现在另一个之下。但是当我插入 imageView 代码时,应用程序在拍照后立即崩溃。
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);
}
日志
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)
【问题讨论】:
-
如何使用适配器创建一个列表并在每次用户添加新照片时添加一个新的空行?只有当其中有数据并且完成时,您才需要保存新行:)
-
@PierGiorgioMisley 在这个阶段我不关心保存数据,只关心显示它。由于无法事先知道用户将拍摄多少张图片以及需要多少张图片视图,因此我将动态添加图片视图。
-
您不需要保存数据来使用我的解决方案,您只需有一个存储所有内容的列表,然后您将在保存时添加一个空条目以显示空行:)跨度>
标签: android android-layout android-layoutparams