Ski*_*ᴉʞS 13 android android-custom-view android-layout android-view
我正在尝试创建一个可以ImageView在您的设备上移动的应用程序,例如拖动,当我放置75%ImageView的屏幕外显示Toast例如.我一直在阅读有关MotionEvent和onTouchListener我已经遵循了这一问题,但它并没有说服我.
我目前的代码是:
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
int windowwidth;
int windowheight;
private ImageView mImageView;
private ViewGroup mRrootLayout;
private int _xDelta;
private int _yDelta;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
windowwidth = displaymetrics.widthPixels;
windowheight = displaymetrics.heightPixels;
mRrootLayout = (ViewGroup) findViewById(R.id.root);
mImageView = (ImageView) mRrootLayout.findViewById(R.id.im_move_zoom_rotate);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(150, 150);
mImageView.setLayoutParams(layoutParams);
mImageView.setOnTouchListener(this);
}
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
if(X == 0){
Toast.makeText(this, "OUT", Toast.LENGTH_SHORT).show();
}
else if (Y == 0){
Toast.makeText(this, "OUT", Toast.LENGTH_SHORT).show();
}
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
view.setLayoutParams(layoutParams);
break;
}
mRrootLayout.invalidate();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我做这些if,并else if只知道,如果ImageView是失控的设备,在设备的左侧和右侧看起来很不错,但我想使它更清洁,不hardwritted,我也没有得到LayoutParams(150,150)为什么150?另外我不明白为什么我必须创建一个RelativeLayout.LayoutParams为什么我必须放
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
Run Code Online (Sandbox Code Playgroud)
我之所以这样做是if/else if因为我想在用户想要ImageView放出设备时删除,所以我需要控制他何时尝试,此刻我只得到它TOP/LEFT/RIGHT而不是向下,我也得到尺寸我的设备只是尝试如果X或Y与高度相同或只是显示Toast但它没有正确地做.
现在我的ImageView是,ic_launcher但它会更大(几乎是中间屏幕).
如果你知道任何其他方式更容易或更干净,请随意把它放在这里,我不关心我的代码,我可以适应它,我只是希望它清晰,而不是硬编码.
你的日常工作大部分都有效.在下面的代码中,我已经注释掉了不需要的部分,并为那些需要解释的部分制作了符号.以下是成品的样子:
此图形说明了如何计算左边距.相同类型的计算适用于上边距.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
int windowwidth; // Actually the width of the RelativeLayout.
int windowheight; // Actually the height of the RelativeLayout.
private ImageView mImageView;
private ViewGroup mRrootLayout;
private int _xDelta;
private int _yDelta;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// We are interested when the image view leaves its parent RelativeLayout
// container and not the screen, so the following code is not needed.
// DisplayMetrics displaymetrics = new DisplayMetrics();
// this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
// windowwidth = displaymetrics.widthPixels;
// windowheight = displaymetrics.heightPixels;
mRrootLayout = (ViewGroup) findViewById(R.id.root);
mImageView = (ImageView) mRrootLayout.findViewById(R.id.im_move_zoom_rotate);
// These these following 2 lines that address layoutparams set the width
// and height of the ImageView to 150 pixels and, as a side effect, clear any
// params that will interfere with movement of the ImageView.
// We will rely on the XML to define the size and avoid anything that will
// interfere, so we will comment these lines out. (You can test out how a layout parameter
// can interfere by setting android:layout_centerInParent="true" in the ImageView.
// RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(150, 150);
// RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(150, 150);
// mImageView.setLayoutParams(layoutParams);
mImageView.setOnTouchListener(this);
// Capture the width of the RelativeLayout once it is laid out.
mRrootLayout.post(new Runnable() {
@Override
public void run() {
windowwidth = mRrootLayout.getWidth();
windowheight = mRrootLayout.getHeight();
}
});
}
// Tracks when we have reported that the image view is out of bounds so we
// don't over report.
private boolean isOutReported = false;
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
// Check if the image view is out of the parent view and report it if it is.
// Only report once the image goes out and don't stack toasts.
if (isOut(view)) {
if (!isOutReported) {
isOutReported = true;
Toast.makeText(this, "OUT", Toast.LENGTH_SHORT).show();
}
} else {
isOutReported = false;
}
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// _xDelta and _yDelta record how far inside the view we have touched. These
// values are used to compute new margins when the view is moved.
_xDelta = X - view.getLeft();
_yDelta = Y - view.getTop();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_POINTER_UP:
// Do nothing
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view
.getLayoutParams();
// Image is centered to start, but we need to unhitch it to move it around.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
lp.removeRule(RelativeLayout.CENTER_HORIZONTAL);
lp.removeRule(RelativeLayout.CENTER_VERTICAL);
} else {
lp.addRule(RelativeLayout.CENTER_HORIZONTAL, 0);
lp.addRule(RelativeLayout.CENTER_VERTICAL, 0);
}
lp.leftMargin = X - _xDelta;
lp.topMargin = Y - _yDelta;
// Negative margins here ensure that we can move off the screen to the right
// and on the bottom. Comment these lines out and you will see that
// the image will be hemmed in on the right and bottom and will actually shrink.
lp.rightMargin = view.getWidth() - lp.leftMargin - windowwidth;
lp.bottomMargin = view.getHeight() - lp.topMargin - windowheight;
view.setLayoutParams(lp);
break;
}
// invalidate is redundant if layout params are set or not needed if they are not set.
// mRrootLayout.invalidate();
return true;
}
private boolean isOut(View view) {
// Check to see if the view is out of bounds by calculating how many pixels
// of the view must be out of bounds to and checking that at least that many
// pixels are out.
float percentageOut = 0.50f;
int viewPctWidth = (int) (view.getWidth() * percentageOut);
int viewPctHeight = (int) (view.getHeight() * percentageOut);
return ((-view.getLeft() >= viewPctWidth) ||
(view.getRight() - windowwidth) > viewPctWidth ||
(-view.getTop() >= viewPctHeight) ||
(view.getBottom() - windowheight) > viewPctHeight);
}
}
Run Code Online (Sandbox Code Playgroud)
activity_main.xml中
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/im_move_zoom_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/circle" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7044 次 |
| 最近记录: |