限制在相对布局中的自定义视图。

huangapple go评论73阅读模式
英文:

restrict a custom view in a relative layout

问题

以下是翻译好的部分:

我是Android的新手,遇到了一些问题。我试图创建一个简单的绘图应用,在页面顶部显示一个示例,在其下方显示一个正方形的绘图区域。目标是显示一个字母,孩子需要在下方的绘图区域中进行模仿练习。

我在布局中遇到了将绘图类包含进去并限制其边界的问题。

这是主要的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/exampleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/drawingBoard"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/exampleText">
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

这是PaintView类:

import android.app.ActionBar;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

public class PaintView extends View {

    public ViewGroup.LayoutParams param;
    private Path path = new Path();
    private Paint brush = new Paint();

    public PaintView(MainActivity context) {
        super(context);
        brush.setAntiAlias(true);
        brush.setColor(Color.RED);
        brush.setStyle(Paint.Style.STROKE);
        brush.setStrokeJoin(Paint.Join.ROUND);
        brush.setStrokeWidth(8f);

        param = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float pointX = event.getX();
        float pointY = event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                path.moveTo(pointX,pointY);
                return true;

            case MotionEvent.ACTION_MOVE:
                path.lineTo(pointX,pointY);
                break;
            default:
                return  false;
        }
        postInvalidate();
        return  false;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawPath(path,brush);
    }
}

在MainActivity中的调用方式如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    PaintView paintView = new PaintView(this);
    setContentView(paintView);
}

我需要将绘图区域适应"drawingBoard"中。

这不一定是正确的方法,但这是我目前的进展。

提前感谢您的帮助!

英文:

I am new to android and I am a bit stuck. I am trying to create a simple drawing app which shows an example on the top of the page and a square space for it in below it. Aim is to display a letter and a kid needs to practice in replicating it.

I have troubles including the drawing class in the layout which needs to restrict its boundaries.

this is the main layout

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
xmlns:tools=&quot;http://schemas.android.com/tools&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
tools:context=&quot;.MainActivity&quot;&gt;
&lt;TextView
android:id=&quot;@+id/exampleText&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_marginTop=&quot;32dp&quot;
android:text=&quot;TextView&quot;
app:layout_constraintEnd_toEndOf=&quot;parent&quot;
app:layout_constraintStart_toStartOf=&quot;parent&quot;
app:layout_constraintTop_toTopOf=&quot;parent&quot; /&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout
enter code here` android:id=&quot;@+id/drawingBoard&quot;
android:layout_width=&quot;0dp&quot;
android:layout_height=&quot;0dp&quot;
app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
app:layout_constraintEnd_toEndOf=&quot;parent&quot;
app:layout_constraintHorizontal_bias=&quot;0.0&quot;
app:layout_constraintStart_toStartOf=&quot;parent&quot;
app:layout_constraintTop_toBottomOf=&quot;@+id/exampleText&quot;&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

this is the PaintView class

import android.app.ActionBar;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
public class PaintView extends View {
public ViewGroup.LayoutParams param;
private Path path = new Path();
private Paint brush = new Paint();
public PaintView(MainActivity context) {
super(context);
brush.setAntiAlias(true);
brush.setColor(Color.RED);
brush.setStyle(Paint.Style.STROKE);
brush.setStrokeJoin(Paint.Join.ROUND);
brush.setStrokeWidth(8f);
param = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float pointX = event.getX();
float pointY = event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
path.moveTo(pointX,pointY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(pointX,pointY);
break;
default:
return  false;
}
postInvalidate();
return  false;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path,brush);
}

this is how it is called in the Main Activity

  protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PaintView paintView = new PaintView(this);
setContentView(paintView);
}

I need to fit the drawing board into the "drawingBoard".

It is not necessary the right approach, but this is as far as I got.

Thanks in advance

答案1

得分: 0

将自定义视图附加到片段。
这是一种完全不同的方法,因此您将不得不对代码进行许多更改。

另一种方法是将视图以编程方式添加到ConstraintLayout中。
在MainActivity中,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // 删除以下这些行。
    /*
    PaintView paintView = new PaintView(this);
    setContentView(paintView);*/
    ConstraintLayout parentLayout = (ConstraintLayout)findViewById(R.id.drawingBoard);
    ConstraintSet set = new ConstraintSet();

    PaintView paintView = new PaintView(this);
    // 设置视图ID,否则getId()将返回-1
    paintView.setId(View.generateViewId());
    parentLayout.addView(paintView, 0);

    set.clone(parentLayout);
    // 连接视图的起始点和终点,在这种情况下是将子视图的顶部连接到父视图的顶部。

    set.connect(paintView.getId(),
    ConstraintSet.TOP,parentLayout.getId(), 
    ConstraintSet.TOP, 60);
    // ... 类似地添加其他约束
    set.applyTo(parentLayout);
}

(请注意,这仅是翻译后的代码,不包括原始内容。)

英文:

Attach the customview to a fragment.
This is a completely different approach so you will have to make a lot of changes to your code.

The other approach would be adding the view programmatically to the ConstraintLayout.
In MainActivity,

protected void onCreate(Bundle  savedInstanceStatee) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//remove those lines.
/*
PaintView paintView = new PaintView(this);
setContentView(paintView);*/
ConstraintLayout parentLayout = (ConstraintLayout)findViewById(R.id.drawingBoard);
ConstraintSet set = new ConstraintSet();
PaintView paintView = new PaintView(this);
// set view id, else getId() returns -1
paintView.setId(View.generateViewId());
layout.addView(paintView, 0);
set.clone(parentLayout);
// connect start and end point of views, in this 
case top of child to top of parent.
set.connect(paintView.getId(),
ConstraintSet.TOP,parentLayout.getId(), 
ConstraintSet.TOP, 60);
// ... similarly add other constraints
set.applyTo(parentLayout);
}

答案2

得分: 0

在该活动中,您正在用以下代码覆盖内容视图:

setContentView(paintView);

请移除该行。

在XML中添加PaintView

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/exampleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!-- TODO: Replace with your package name -->
    <com.example.PaintView
        android:id="@+id/drawingBoard"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/exampleText" />

</androidx.constraintlayout.widget.ConstraintLayout>

采用这种方式,您需要在其构造函数中填充自定义视图:

public class PaintView extends ConstraintLayout {
    public PaintView(@NonNull Context context) {
        super(context);
        init();
    }

    public PaintView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PaintView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public PaintView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    public void init() {
        inflate(getContext(), R.layout.layout_product_item, this);
    }
}

要从活动代码中与PaintView 交互,您可以使用以下代码:

PaintView paintView = (PaintView) findViewById(R.id.drawingBoard);
英文:

In the activity you are overwriting the content view with just the paint view:
setContentView(paintView);

Remove that line.

Add the PaintView in XML instead:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
xmlns:tools=&quot;http://schemas.android.com/tools&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
tools:context=&quot;.MainActivity&quot;&gt;
&lt;TextView
android:id=&quot;@+id/exampleText&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_marginTop=&quot;32dp&quot;
android:text=&quot;TextView&quot;
app:layout_constraintEnd_toEndOf=&quot;parent&quot;
app:layout_constraintStart_toStartOf=&quot;parent&quot;
app:layout_constraintTop_toTopOf=&quot;parent&quot; /&gt;
&lt;!-- TODO: Replace with your package name --&gt;
&lt;com.example.PaintView
android:id=&quot;@+id/drawingBoard&quot;
android:layout_width=&quot;0dp&quot;
android:layout_height=&quot;0dp&quot;
app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
app:layout_constraintEnd_toEndOf=&quot;parent&quot;
app:layout_constraintStart_toStartOf=&quot;parent&quot;
app:layout_constraintTop_toBottomOf=&quot;@+id/exampleText&quot; /&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

With this approach you have to inflate the custom view in its constructors:

public class PaintView extends ConstraintLayout {
public PaintView(@NonNull Context context) {
super(context);
init();
}
public PaintView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public PaintView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public PaintView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public void init() {
inflate(getContext(), R.layout.layout_product_item, this);
}
}

To interact with the PaintView from the activity code you can do:

PaintView paintView = (PaintView) findViewById(R.id.drawingBoard);

huangapple
  • 本文由 发表于 2020年9月20日 15:59:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/63976794.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定