- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想制作一个自定义按钮,就像这个程序所做的那样,可能使用径向渐变。
我将 View 子类化,绘制三个形状的可绘制对象,然后绘制文本。文本似乎偏离了中心,所以我试图为文本绘制一个边界矩形,但没有成功。并计划添加一个点击监听器来获得类似按钮的行为。
也许我应该将按钮子类化,但是在哪里绘制我的可绘制对象,这样它们就不会被正在绘制的按钮文本弄乱。
任何指针将不胜感激。
谢谢
Edit2:见下面的第二次尝试。
Edit3:赏金的原因是找出子类化 drawable 不起作用的原因。梯度不是那么重要。
edit4:在 DrawableView::OnDraw() 中的 getTextBounds() 之前发现了 drawRect。
package acme.drawables;
import android.content.*;
import android.content.pm.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.graphics.drawable.shapes.*;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.*;
import android.view.Menu;
import android.view.View;
import android.widget.*;
import static java.lang.Math.*;
public class MainActivity extends AppCompatActivity {
DrawableView drawableView;
LinearLayout row(boolean isRow1) {
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(w,d);
int m=(int)round(w*margin);
layoutParams.setMargins(m,m,m,m);
for(int i=0;i<n;i++)
layout.addView(drawableView=new DrawableView(this,i,isRow1),layoutParams);
return layout;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
DisplayMetrics metrics=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
w=d=(int)round(metrics.densityDpi);
LinearLayout row1=row(true);
LinearLayout row2=row(false);
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(row1);
layout.addView(row2);
LinearLayout l=new LinearLayout(this);
setContentView(layout);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
public class DrawableView extends View {
public DrawableView(Context context,int column,boolean isRow1) {
super(context);
setBackgroundColor(Color.TRANSPARENT);
this.column=column;
text=""+(char)('0'+column);
int r=(int)round(w*radius);
d0=new ShapeDrawable(new RoundRectShape(new float[]{r,r,r,r,r,r,r,r},null,null));
d0.getPaint().setColor(0xff000000);
d0.setBounds(0,0,w,d);
d1=new ShapeDrawable(new RoundRectShape(new float[]{r,r,r,r,r,r,r,r},null,null));
d1.getPaint().setColor(on[column]);
d1.setBounds(edge,edge,w-edge,d-edge);
d2=new ShapeDrawable(new RoundRectShape(new float[]{r,r,r,r,r,r,r,r},null,null));
int b=(int)round(w*border);
d2.setBounds(b/2,b/2,w-b/2,d-b/2);
d2.getPaint().setColor(isRow1?on[column]:off[column]);
}
protected void onDraw(Canvas canvas) {
d0.draw(canvas);
d1.draw(canvas);
d2.draw(canvas);
Paint paint = new Paint();
//paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
//canvas.drawPaint(paint);
paint.setColor(Color.CYAN);
paint.setTextSize(w*95/100);
Rect r=new Rect();
paint.getTextBounds(text,0,1,r); // were switched
canvas.drawRect(r,paint); // were switched
int x=(w-r.width())/2,y=(d-r.height())/2;
paint.setColor(Color.BLACK);
canvas.drawText(text,x,d-y,paint);
}
final int column;
final String text;
ShapeDrawable d0, d1, d2;
}
final int n=5, edge=1;
double margin=.10, radius=.05, border=.15;
int w, d;
final int[] on=new int[]{0xffff0000,0xffffff00,0xff00ff00,0xff0000ff,0xffff8000};
final int[] off=new int[]{0xff800000,0xff808000,0xff008000,0xff000080,0xff804000};
}
此版本尝试子类化 drawable 并使用按钮。但是按钮的绘图似乎干扰了我绘制可绘制的形状。看起来边界被忽略了。
package acme.drawables;
import android.content.*;
import android.content.pm.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.graphics.drawable.shapes.*;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.*;
import android.view.Menu;
import android.view.View;
import android.widget.*;
import static java.lang.Math.*;
public class MainActivity extends AppCompatActivity {
LinearLayout row(boolean isRow1) {
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(w,d);
int m=(int)round(w*margin);
layoutParams.setMargins(m,m,m,m);
if(true)
for(int i=0;i<n;i++) { // subclass drawable
Button b=new Button(this);
b.setText(""+(char)('0'+i));
b.setBackground(new MyDrawable(i,i/n%2==0));
layout.addView(b,layoutParams);
}
else
for(int i=0;i<n;i++) // use drawable view with canvas draw text
layout.addView(drawableView=new DrawableView(i,isRow1),layoutParams);
return layout;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
DisplayMetrics metrics=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
w=d=(int)round(metrics.densityDpi);
LinearLayout row1=row(true);
LinearLayout row2=row(false);
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(row1);
layout.addView(row2);
LinearLayout l=new LinearLayout(this);
setContentView(layout);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
public class MyDrawable extends Drawable {
public MyDrawable(int column,boolean isRow1) {
drawableView=new DrawableView(column,isRow1);
}
public void setAlpha(int alpha) {
System.out.println("ignoring set alpha to: "+alpha);
}
public void setColorFilter(ColorFilter colorFilter) {
System.out.println("ignoring set color filter to: "+colorFilter);
}
public int getOpacity() {
return PixelFormat.OPAQUE;
}
public void draw(Canvas canvas) {
System.out.println(this+" is drawing.");
drawableView.d0.draw(canvas);
System.out.println("d0 bounds: "+drawableView.d0.getBounds());
drawableView.d1.draw(canvas);
System.out.println("d1 bounds: "+drawableView.d1.getBounds());
drawableView.d2.draw(canvas);
System.out.println("d2 bounds: "+drawableView.d2.getBounds());
}
final DrawableView drawableView; // cheat by delegating
}
public class DrawableView extends View {
public DrawableView(int column,boolean isRow1) {
super(MainActivity.this);
setBackgroundColor(Color.TRANSPARENT);
this.column=column;
text=""+(char)('0'+column);
int r=(int)round(w*radius);
d0=new ShapeDrawable(new RoundRectShape(new float[]{r,r,r,r,r,r,r,r},null,null));
d0.getPaint().setColor(0xff000000);
d0.setBounds(0,0,w,d);
d1=new ShapeDrawable(new RoundRectShape(new float[]{r,r,r,r,r,r,r,r},null,null));
d1.getPaint().setColor(on[column]);
d1.setBounds(edge,edge,w-edge,d-edge);
d2=new ShapeDrawable(new RoundRectShape(new float[]{r,r,r,r,r,r,r,r},null,null));
int b=(int)round(w*border);
d2.setBounds(b/2,b/2,w-b/2,d-b/2);
d2.getPaint().setColor(isRow1?on[column]:off[column]);
}
protected void onDraw(Canvas canvas) {
d0.draw(canvas);
d1.draw(canvas);
d2.draw(canvas);
Paint paint=new Paint();
//paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
//canvas.drawPaint(paint);
paint.setColor(Color.CYAN);
paint.setTextSize(w*95/100);
Rect r=new Rect();
canvas.drawRect(r,paint);
paint.getTextBounds(text,0,1,r);
int x=(w-r.width())/2, y=(d-r.height())/2;
paint.setColor(Color.BLACK);
canvas.drawText(text,x,d-y,paint);
}
final int column;
final String text;
ShapeDrawable d0, d1, d2;
}
DrawableView drawableView;
final int n=5, edge=1;
double margin=.10, radius=.05, border=.15;
int w, d;
final int[] on=new int[]{0xffff0000,0xffffff00,0xff00ff00,0xff0000ff,0xffff8000};
final int[] off=new int[]{0xff800000,0xff808000,0xff008000,0xff000080,0xff804000};
}
最佳答案
1) 在您的 DrawableView
中使用对齐在中心绘制文本(应该有助于文本似乎偏离中心):
paint.setTextAlign(Align.CENTER); // <- should help you with centering
paint.getTextBounds(text, 0, 1, r);
int x = w / 2, y = (d - r.height()) / 2; // <- was updated too
2) 回答你的问题赏金的原因是找出子类化 drawable 不起作用的原因:
我想这是因为您在 MyDrawable
中创建了 DrawableView
并且没有将它添加到任何容器,这意味着您没有测量和布局它。因此,它的高度和宽度可能为零。
3) 我建议您使用 Button 而不是自定义 View 和可绘制对象。您从 Button 扩展并在 onDraw 方法的末尾进行额外的绘图,如下所示:
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// your custom drawing over button
}
原始错误答案
赏金的原因是找出子类化 drawable 不起作用的原因
尝试检查是否需要调用:
super.onDraw(canvas)
在 DrawableView.onDraw
super.draw(canvas)
在 MyDrawable.draw
关于java - Android - 具有形状可绘制对象和以编程方式渐变的自定义按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34086303/
我学习 SDL 二维编程已有一段时间了,现在我想创建一个结合使用 SDL 和 OpenGL 的程序。我是这样设置的: SDL_Init(SDL_INIT_VIDEO); window = SDL_Cr
尝试查找可在地块中使用的不同类型项目的列表 来自不同样本的投影类型: projection = list(type = "equirectangular") projection = list(typ
我正在尝试使用 Java Graphics API 绘制 GIF,但无法使用下面的代码成功绘制 GIF。仅绘制 GIF 的第一张图像或缩略图,但不播放。 public void paintCompon
我目前正在使用 JFrame 并尝试绘制一个矩形,但我不知道如何执行代码 paint(Graphics g),如何获取 Graphics 对象? package com.raggaer.frame;
这个领域的新手,希望得到一些帮助。 我有一个"Missile.java" 类,我在那里画东西。我想绘制一个 ImageView,我正在使用以下代码: ImageView v = (ImageView)
下面列出了圆形的例子 这是我的 JavaScript 代码。 最佳答案 假设您的 randomColor 是正确的,您只需要: 从 canvas.onclick 中移除 context.clearR
我在绘制和缩放 ImageView 时遇到问题。请帮帮我.. 当我画一些东西然后拖动或缩放图像时 - 绘图保留在原处,如您在屏幕截图中所见。而且我只需要简单地在图片上绘图,并且可以缩放和拖动这张图片。
我们可以在形式之外绘制图像和文本...我的意思是在字面上... 我知道问这个问题很愚蠢但是我们能不能... 最佳答案 您可以通过创建表单并将其 TransparentColor 属性设置为背景色来“作
我在绘制/布局期间收到 3 个对象分配警告 super.onDraw(canvas); canvas.drawColor(Color.WHITE); Paint textPaint = new Pai
我有一个示例时间序列数据框: df = pd.DataFrame({'year':'1990','1991','1992','1993','1994','1995','1996',
我试图想出一种简洁的方法来绘制 R 数据框中所有列的 GridView 。问题是我的数据框中既有离散值又有数值。为简单起见,我们可以使用 R 提供的名为 iris 的示例数据集。我会使用 par(mf
我有一个由 10 列和 50 行组成的 data.frame。我使用 apply 函数逐列计算密度函数。现在我想绘制我一次计算的密度。 换句话说,而不是绘图... plot(den[[1]]) plo
我想知道我们如何才能在第一个和第二个组件之外绘制个人,如下所示: 最佳答案 这可能有效: pc.cr <- princomp(USArrests, cor = TRUE) pairs(pc.cr$lo
我是Pandas和matplotlib的新手,想绘制此DataFrame season won team matches pct_won 0 20
我正在尝试为 distplot 子图编写一个 for 循环。 我有一个包含许多不同长度列的数据框。 (不包括 NaN 值) fig = make_subplots( rows=len(asse
我想创建一个具有密度的 3d 图。 我使用函数 density 首先为特定的 x 值创建一个二维图,然后该函数创建密度并将它们放入 y 变量中。现在我有第二组 x 值并将其再次放入密度函数中,然后我得
全部, 我一直在研究全局所有 MTB 步道的索引。我是 Python 人,所以对于所有涉及的步骤,我都尝试使用 Python 模块。 我能够像这样从 OSM 立交桥 API 中获取关系: from O
我正在使用 e1071 包中的支持向量机对我的数据进行分类,并希望可视化机器实际如何进行分类。但是,在使用 plot.svm 函数时,出现无法解决的错误。 脚本: library("e1071") d
我制作了以下图表,它是使用 xts 对象创建的。 我使用的代码很简单 plot(graphTS1$CCLL, type = "l", las = 2, ylab = "(c)\nCC for I
在绘制状态图时,您如何知道哪些状态放在框中,哪些状态用于转换箭头?我注意到转换也是状态。 我正在查看 this page 上的图 1 : 最佳答案 转换不是状态。转换是将对象从一种状态移动到下一种状态
我是一名优秀的程序员,十分优秀!