内部に 3 つの画像ボタンを含む EditText が必要でしたが、これは相対レイアウトを使用し、本質的に画像ボタンを edittext の上に配置することで作成できました。何かのようなもの:
EditText がフォーカスされているときにボタン IB1 と IB2 のスワップをアニメーション化し、フォーカスを失ったときに再びスワップしようとしています。私もこれを行うことができましたが、ボタン LayoutParams onAnimationEnd を更新しようとすると問題が発生します(そうしないと、ピクセルは画面上の位置を変更しますが、基になるビューは元の位置のままです)。
問題: ImageButton layoutParams を更新すると、EditText フォーカス イベントが再度トリガーされるように見えます。edittext ウィジェットをタップすると、ボタンが永久に前後に移動し始めます。関連する XML:
<RelativeLayout
android:id="@+id/commentView"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/commentBox"
android:maxLines="1"
android:scrollHorizontally="true"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:inputType="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:paddingRight="100dp"
android:paddingLeft="55dp"
android:background="@drawable/comment"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:hint="Your comment..."
/>
<ImageButton
android:id="@+id/share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/commentBox"
android:layout_marginRight="2dp"
android:src="@drawable/sharebutton"
android:background="@null"
android:layout_centerVertical="true" />
<ImageButton
android:id="@+id/like"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/commentBox"
android:src="@drawable/likebutton"
android:background="@null"
android:layout_marginLeft="4dp"
android:layout_centerVertical="true" />
<ImageButton
android:id="@+id/commentimagebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/share"
android:src="@drawable/commentbutton"
android:background="@null"
android:layout_marginRight="4dp"
android:layout_centerVertical="true" />
関連するコード スニペット:
commentBox.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
RelativeLayout parent = (RelativeLayout) view.getParent();
ImageButton commentView = (ImageButton) parent.findViewById(R.id.commentimagebutton);
ImageButton likeView = (ImageButton) parent.findViewById(R.id.like);
if (hasFocus) {
swapViews(likeView, commentView);
}
}
});
と:
private void swapViews(final ImageButton firstView, final ImageButton secondView)
{
//get view positions and calculate distance
int secondPosition[] = new int[2];
int firstPosition[] = new int[2];
secondView.getLocationOnScreen(secondPosition);
firstView.getLocationOnScreen(firstPosition);
int moveDistance = Math.abs(secondPosition[0]-firstPosition[0]);
//get LayoutParams
final RelativeLayout.LayoutParams firstViewLayout = (RelativeLayout.LayoutParams) firstView.getLayoutParams();
final RelativeLayout.LayoutParams secondViewLayout = (RelativeLayout.LayoutParams) secondView.getLayoutParams();
//set up animations
TranslateAnimation moveLeft = new TranslateAnimation( 0, -moveDistance, 0, 0);
moveLeft.setDuration(1000);
moveLeft.setFillAfter(true);
TranslateAnimation moveRight = new TranslateAnimation( 0, moveDistance, 0, 0);
moveRight.setDuration(1000);
moveRight.setFillAfter(true);
if (secondPosition[0] > firstPosition[0]) {
moveLeft.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
//change positions
secondView.clearAnimation();
secondViewLayout.addRule(RelativeLayout.ALIGN_LEFT, R.id.commentBox);
secondViewLayout.addRule(RelativeLayout.LEFT_OF, 0);
secondView.setLayoutParams(secondViewLayout);
}
});
moveRight.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
//change positions
firstView.clearAnimation();
firstViewLayout.addRule(RelativeLayout.ALIGN_LEFT, 0);
firstViewLayout.addRule(RelativeLayout.LEFT_OF, R.id.share);
firstView.setLayoutParams(firstViewLayout);
}
});
//animate
secondView.startAnimation(moveLeft);
firstView.startAnimation(moveRight);
} else {
moveLeft.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
//change positions
firstView.clearAnimation();
firstViewLayout.addRule(RelativeLayout.ALIGN_LEFT, R.id.commentBox);
firstViewLayout.addRule(RelativeLayout.LEFT_OF, 0);
firstView.setLayoutParams(firstViewLayout);
}
});
moveRight.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
//change positions
secondView.clearAnimation();
secondViewLayout.addRule(RelativeLayout.ALIGN_LEFT, 0);
secondViewLayout.addRule(RelativeLayout.LEFT_OF, R.id.share);
secondView.setLayoutParams(secondViewLayout);
}
});
//animate
secondView.startAnimation(moveRight);
firstView.startAnimation(moveLeft);
}
}
注: API レベル 10 を使用しています。また、EditText で onClickListener を使用しようとしましたが、1. edittext の最初のタップでフォーカスされ、2 回目のタップのみがクリックとして検出され、2. edittext がフォーカスを失うと、ボタンは元に戻ります。
ありがとう!