自定义View多层圆实现

在我们想做自定义view的时候应该先根据需要在values下创建一个atts.xml文件来定义属性如下:

<declare-styleable name="ZFXView">
    <attr name="centerx" format="integer"></attr>
    <attr name="pintx" format="integer"></attr>
    <attr name="text" format="string"></attr>
    <attr name="centercolor" format="color"></attr>
    <attr name="textsize" format="integer"></attr>
</declare-styleable>


这是我们会需要到的属性,分别是大圆的半径,小圆的半径,文字,文字大小,大圆的颜色




当我们定义完所需要的属性之后,需要自定义一个类用来继承View,重写view的三个构造方法


在两个参数中的方法中,先得到以上我们自定义的属性,代码如下:

private void initAttrs(AttributeSet attrs) {
         //得到自定义属性的结果集 
 TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ZFXView);
    centerx = typedArray.getInt(R.styleable.ZFXView_centerx, -1);
    pintx = typedArray.getInt(R.styleable.ZFXView_pintx, -1);
    textsize = typedArray.getInt(R.styleable.ZFXView_textsize, -1);
    text = typedArray.getString(R.styleable.ZFXView_text);
    color = typedArray.getColor(R.styleable.ZFXView_centercolor, -1);
}
接着重写 onMeasure方法来控制我们控件的大小。

在onDraw里面得到画布,以及对画笔进行一系列的操作,先画第一个大圆,然后画里面的小圆。最后在画字。完整代码如下:
public class ZFXView extends View {

    private int centerx;
    private int pintx;
    private int textsize;
    private String text;
    private int color;
    private int cenY;
    private int cenX;
    private float x;
    private float y;
    public OnsrolleyClickLiener listener;
    public interface  OnsrolleyClickLiener{
        void srolleyClickLiener(String text);
    }
    public void setOnCircleClickListener(OnsrolleyClickLiener listener){
        this.listener=listener;
    }

    public ZFXView(Context context) {
        super(context);
    }
    public ZFXView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
    }
    public ZFXView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }
    private void initAttrs(AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ZFXView);
        centerx = typedArray.getInt(R.styleable.ZFXView_centerx, -1);
        pintx = typedArray.getInt(R.styleable.ZFXView_pintx, -1);
        textsize = typedArray.getInt(R.styleable.ZFXView_textsize, -1);
        text = typedArray.getString(R.styleable.ZFXView_text);
        color = typedArray.getColor(R.styleable.ZFXView_centercolor, -1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(centerx*2,centerx*2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        cenX = centerx;
        cenY = centerx;
        canvas.drawColor(Color.GREEN);

        Paint paint=new Paint();
        //设置画笔的样式为空心
        paint.setStyle(Paint.Style.FILL);
       paint.setColor(color);
        //抗锯齿
        paint.setAntiAlias(true);
        //画大圆
        canvas.drawCircle(cenX,cenY,centerx,paint);

        paint.setColor(Color.WHITE);
        //画小圆
        canvas.drawCircle(cenX,cenY,pintx,paint);

        paint.setTextSize(textsize);
        paint.setColor(Color.BLACK);
        //画字
        canvas.drawText(text,cenX-text.length()/2*textsize,cenY+textsize/2,paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
           if(event.getAction()==MotionEvent.ACTION_DOWN){
               x = event.getX();
               y = event.getY();
               Log.i("xxx",x+"aaaaaaa"+y);
               double sqrt = Math.sqrt((cenX - x) * (cenX - x) + (cenY - y) * (cenY - y));
               Log.i("xxx",sqrt+"");
               if(sqrt<pintx){
                   Toast.makeText(getContext(), "小圆内", Toast.LENGTH_SHORT).show();
               }else if(sqrt>pintx&&sqrt<centerx){
                   Toast.makeText(getContext(), "圆环内", Toast.LENGTH_SHORT).show();
               }else {
                   Toast.makeText(getContext(), "圆环外", Toast.LENGTH_SHORT).show();
                   listener.srolleyClickLiener("圆环外");
               }
           }
        return super.onTouchEvent(event);

    }
}

代码写完之后该对布局进行书写,在布局中,首先得到自定义的控件,对其我们所有的自定义属性进行赋值。
<yuekao.bawei.com.customstudy.view.ZFXView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/zfx"
    app:text="圆环"
    app:textsize="20"
    app:pintx="50"
    app:centerx="100"
    app:centercolor="#ff0"
    android:layout_centerInParent="true"
    />
,其中在点击事件中,还用到了接口回调。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,下面是一个使用PyTorch实现简单Transformer的示例代码: ``` import torch import torch.nn as nn import torch.nn.functional as F class MultiHeadAttention(nn.Module): def __init__(self, d_model, n_heads): super(MultiHeadAttention, self).__init__() self.d_model = d_model self.n_heads = n_heads self.d_k = d_model // n_heads self.linear_q = nn.Linear(d_model, d_model) self.linear_k = nn.Linear(d_model, d_model) self.linear_v = nn.Linear(d_model, d_model) self.linear_out = nn.Linear(d_model, d_model) def forward(self, x): q = self.linear_q(x) k = self.linear_k(x) v = self.linear_v(x) q = q.view(q.size(0), -1, self.n_heads, self.d_k).transpose(1, 2) k = k.view(k.size(0), -1, self.n_heads, self.d_k).transpose(1, 2) v = v.view(v.size(0), -1, self.n_heads, self.d_k).transpose(1, 2) scores = torch.matmul(q, k.transpose(-1, -2)) / torch.sqrt(torch.tensor(self.d_k, dtype=torch.float32)) attn_weights = F.softmax(scores, dim=-1) context = torch.matmul(attn_weights, v) context = context.transpose(1, 2).contiguous().view(context.size(0), -1, self.d_model) out = self.linear_out(context) return out class PositionwiseFeedforward(nn.Module): def __init__(self, d_model, d_ff): super(PositionwiseFeedforward, self).__init__() self.linear1 = nn.Linear(d_model, d_ff) self.linear2 = nn.Linear(d_ff, d_model) def forward(self, x): x = F.relu(self.linear1(x)) x = self.linear2(x) return x class EncoderLayer(nn.Module): def __init__(self, d_model, n_heads, d_ff): super(EncoderLayer, self).__init__() self.multi_head_attention = MultiHeadAttention(d_model, n_heads) self.layer_norm1 = nn.LayerNorm(d_model) self.positionwise_feedforward = PositionwiseFeedforward(d_model, d_ff) self.layer_norm2 = nn.LayerNorm(d_model) def forward(self, x): attn_out = self.multi_head_attention(x) x = self.layer_norm1(x + attn_out) ffn_out = self.positionwise_feedforward(x) out = self.layer_norm2(x + ffn_out) return out class TransformerEncoder(nn.Module): def __init__(self, n_layers, d_model, n_heads, d_ff): super(TransformerEncoder, self).__init__() self.encoder_layers = nn.ModuleList([EncoderLayer(d_model, n_heads, d_ff) for _ in range(n_layers)]) def forward(self, x): for layer in self.encoder_layers: x = layer(x) return x ``` 这个示例代码实现了一个简单的Transformer编码器,包括一个多头注意力层、一个位置前馈网络层和一些残差连接和归一化层。您可以使用该代码来训练和测试您自己的Transformer模型。 ### 回答2: Transformer 是一种非常流行的神经网络模型,用于自然语言处理任务,比如机器翻译。PyTorch 是一个广泛使用的深度学习框架,它具有易用性和灵活性。下面我将简要介绍如何使用 PyTorch 实现一个简单的 Transformer 模型。 首先,我们需要导入所需的库和模块。在 PyTorch 中,我们可以使用 `torch.nn` 库来构建神经网络模型,使用 `torch.nn.functional` 库来实现一些常用的函数。 接下来,我们需要定义 Transformer 模型的各个组件。Transformer 模型包含多层的自注意力机制和前馈神经网络。我们可以使用 PyTorch 中的 `torch.nn.TransformerEncoderLayer` 和 `torch.nn.TransformerEncoder` 类来实现这些组件。 然后,我们需要定义输入数据的相关处理。这包括数据的向量化、位置编码和打包操作。向量化将输入序列转换为嵌入向量,可以使用 `torch.nn.Embedding` 类来实现。位置编码用于为每个位置的单词提供一个位置向量,可以使用正弦和余弦函数来生成位置编码。最后,我们使用 `torch.nn.utils.rnn.pack_padded_sequence` 方法将数据长度进行压缩,以提高计算效率。 接下来,我们定义一个函数来计算模型的前向传播过程。在这个函数中,我们首先将数据通过嵌入层进行嵌入,然后添加位置编码。然后,我们将数据输入到 TransformerEncoder 中,获取输出。最后,我们通过一个线性层将输出转换为最终的预测结果。 最后,我们需要定义损失函数和优化器。对于分类任务,我们可以使用交叉熵损失函数。对于优化器,我们可以使用随机梯度下降(SGD)或 Adam 优化器。 现在,我们可以使用定义好的模型和相关参数来训练和评估我们的 Transformer 模型了。为了训练模型,我们可以使用随机梯度下降法来更新模型的参数。评估模型时,我们可以计算预测结果和真实标签之间的准确率。 这就是使用 PyTorch 实现一个简单的 Transformer 模型的基本步骤。希望这个回答对你有所帮助! ### 回答3: Transformer是一种强大的神经网络模型,其在自然语言处理任务中表现出色。PyTorch作为一款流行的深度学习框架,提供了实现Transformer模型的便捷工具。 PyTorch中实现Transformer模型的核心是构建多头自注意力机制和前馈神经网络。首先,需要定义一个Encoder对象和一个Decoder对象。 在Encoder中,可以使用nn.Embedding将输入的单词编码为向量表示,然后通过位置编码加上位置信息。之后,输入数据通过多个自注意力层进行处理,每个自注意力层包括一个多头注意力和一个前馈神经网络。多头注意力将输入数据分为多个头,每个头独立计算注意力权重,然后将计算得到的头进行拼接。最后,注意力权重和原始输入数据进行加权求和,再通过前馈神经网络得到输出数据。 在Decoder中,除了包含Encoder中的自注意力层和前馈神经网络,还需要加上一个全连接层进行输出。 在模型的前向传播过程中,将输入数据通过Encoder和Decoder进行处理,最后得到输出数据。可以使用nn.Module模块化地定义Encoder和Decoder,并通过nn.Sequential将它们组合在一起。 最后,在训练过程中,可以利用torch.optim.Adam优化器和交叉熵损失函数进行优化。 以上就是用PyTorch实现简单的Transformer模型的基本步骤。当然,还可以根据具体任务的需求,自定义更多的组件和损失函数。在实际应用中,可以通过调整模型的超参数和进行训练调优来提高模型的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值