- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在努力制作一个像钢笔画圆一样的动画。为此,我尝试使用自定义进度条,并尝试了不同的自定义搜索栏库,但对于带有自定义搜索栏的库,我无法设置拇指。在图像中是我想要的方向。它将从顶部开始并形成一个完整的圆圈。我也制作了圆圈来显示,但我无法添加和同步图像以同时旋转
最佳答案
如果你不想使用库,试试这个
像这样创建一个类
CircularSeekBar
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class CircularSeekBar extends View {
private Context mContext;
private OnSeekChangeListener mListener;
private Paint circleColor;
private Paint innerColor;
private Paint circleRing;
private int angle = 0;
private int startAngle = 270;
private int barWidth = 5;
private int width;
private int height;
private int maxProgress = 100;
private int progress;
private int progressPercent;
private float innerRadius;
private float outerRadius;
private float cx;
private float cy;
private float left;
private float right;
private float top;
private float bottom;
private float dx;
private float dy;
private float startPointX;
private float startPointY;
private float markPointX;
private float markPointY;
private float adjustmentFactor = 100;
private Bitmap progressMark;
private Bitmap progressMarkPressed;
private boolean IS_PRESSED = false;
private boolean CALLED_FROM_ANGLE = false;
private boolean SHOW_SEEKBAR = true;
private RectF rect = new RectF();
{
mListener = new OnSeekChangeListener() {
@Override
public void onProgressChange(CircularSeekBar view, int newProgress) {
}
};
circleColor = new Paint();
innerColor = new Paint();
circleRing = new Paint();
circleColor.setColor(Color.parseColor("#ff33b5e5")); // Set default
innerColor.setColor(Color.WHITE); // Set default background color to black
circleRing.setColor(Color.WHITE);// Set default background color to Gray
circleColor.setAntiAlias(true);
innerColor.setAntiAlias(true);
circleRing.setAntiAlias(true);
circleColor.setStrokeWidth(5);
innerColor.setStrokeWidth(5);
circleRing.setStrokeWidth(5);
circleColor.setStyle(Paint.Style.FILL);
}
public CircularSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
initDrawable();
}
public CircularSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initDrawable();
}
public CircularSeekBar(Context context) {
super(context);
mContext = context;
initDrawable();
}
public void initDrawable() {
progressMark = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_fav_round);
progressMarkPressed = BitmapFactory.decodeResource(mContext.getResources(),
R.mipmap.ic_fav_round);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getWidth(); // Get View Width
height = getHeight();// Get View Height
int size = (width > height) ? height : width; // Choose the smaller
cx = width / 2; // Center X for circle
cy = height / 2; // Center Y for circle
outerRadius = (float) ((size*0.60) / 2); // Radius of the outer circle
innerRadius = outerRadius - barWidth; // Radius of the inner circle
left = cx - outerRadius; // Calculate left bound of our rect
right = cx + outerRadius;// Calculate right bound of our rect
top = cy - outerRadius;// Calculate top bound of our rect
bottom = cy + outerRadius;// Calculate bottom bound of our rect
startPointX = cx; // 12 O'clock X coordinate
startPointY = cy - outerRadius;// 12 O'clock Y coordinate
markPointX = startPointX;// Initial locatino of the marker X coordinate
markPointY = startPointY;// Initial locatino of the marker Y coordinate
rect.set(left, top, right, bottom); // assign size to rect
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(cx, cy, outerRadius, circleRing);
canvas.drawArc(rect, startAngle, angle, true, circleColor);
canvas.drawCircle(cx, cy, innerRadius, innerColor);
if (SHOW_SEEKBAR) {
dx = getXFromAngle();
dy = getYFromAngle();
drawMarkerAtProgress(canvas);
}
super.onDraw(canvas);
}
public void drawMarkerAtProgress(Canvas canvas) {
if (IS_PRESSED) {
canvas.drawBitmap(progressMarkPressed, dx, dy, null);
} else {
canvas.drawBitmap(progressMark, dx, dy, null);
}
}
public float getXFromAngle() {
int size1 = progressMark.getWidth();
int size2 = progressMarkPressed.getWidth();
int adjust = (size1 > size2) ? size1 : size2;
float x = markPointX - (adjust / 2);
return x;
}
public float getYFromAngle() {
int size1 = progressMark.getHeight();
int size2 = progressMarkPressed.getHeight();
int adjust = (size1 > size2) ? size1 : size2;
float y = markPointY - (adjust / 2);
return y;
}
public int getAngle() {
return angle;
}
public void setAngle(int angle) {
this.angle = angle;
float donePercent = (((float) this.angle) / 360) * 100;
float progress = (donePercent / 100) * getMaxProgress();
setProgressPercent(Math.round(donePercent));
CALLED_FROM_ANGLE = true;
setProgress(Math.round(progress));
}
public void setSeekBarChangeListener(OnSeekChangeListener listener) {
mListener = listener;
}
public OnSeekChangeListener getSeekBarChangeListener() {
return mListener;
}
public int getBarWidth() {
return barWidth;
}
public void setBarWidth(int barWidth) {
this.barWidth = barWidth;
}
public interface OnSeekChangeListener {
public void onProgressChange(CircularSeekBar view, int newProgress);
}
public int getMaxProgress() {
return maxProgress;
}
public void setBitmapThumbIcon(int id) {
progressMark = BitmapFactory.decodeResource(mContext.getResources(), id);
progressMarkPressed = BitmapFactory.decodeResource(mContext.getResources(),
id);
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
if (this.progress != progress) {
this.progress = progress;
if (!CALLED_FROM_ANGLE) {
int newPercent = (this.progress * 100) / this.maxProgress;
int newAngle = (newPercent * 360) / 100;
this.setAngle(newAngle);
this.setProgressPercent(newPercent);
}
mListener.onProgressChange(this, this.getProgress());
CALLED_FROM_ANGLE = false;
}
}
public int getProgressPercent() {
return progressPercent;
}
public void setProgressPercent(int progressPercent) {
this.progressPercent = progressPercent;
}
public void setRingBackgroundColor(int color) {
circleRing.setColor(color);
}
public void setBackGroundColor(int color) {
innerColor.setColor(color);
}
public void setProgressColor(int color) {
circleColor.setColor(color);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean up = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
moved(x, y, up);
break;
case MotionEvent.ACTION_MOVE:
moved(x, y, up);
break;
case MotionEvent.ACTION_UP:
up = true;
moved(x, y, up);
break;
}
return true;
}
private void moved(float x, float y, boolean up) {
float distance = (float) Math.sqrt(Math.pow((x - cx), 2) + Math.pow((y - cy), 2));
if (distance < outerRadius + adjustmentFactor && distance > innerRadius - adjustmentFactor && !up) {
IS_PRESSED = true;
markPointX = (float) (cx + outerRadius * Math.cos(Math.atan2(x - cx, cy - y) - (Math.PI / 2)));
markPointY = (float) (cy + outerRadius * Math.sin(Math.atan2(x - cx, cy - y) - (Math.PI / 2)));
float degrees = (float) ((float) ((Math.toDegrees(Math.atan2(x - cx, cy - y)) + 360.0)) % 360.0);
// and to make it count 0-360
if (degrees < 0) {
degrees += 2 * Math.PI;
}
setAngle(Math.round(degrees));
invalidate();
} else {
IS_PRESSED = false;
invalidate();
}
}
public float getAdjustmentFactor() {
return adjustmentFactor;
}
public void setAdjustmentFactor(float adjustmentFactor) {
this.adjustmentFactor = adjustmentFactor;
}
public void ShowSeekBar() {
SHOW_SEEKBAR = true;
}
public void hideSeekBar() {
SHOW_SEEKBAR = false;
}
}
Now use like this in your activity
layout.activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<neel.com.demo.CircularSeekBar
android:id="@+id/circularSeekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="10dp" />
</LinearLayout>
Activity code
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
CircularSeekBar circularSeekbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
circularSeekbar = findViewById(R.id.circularSeekbar);
circularSeekbar.setMaxProgress(100);
circularSeekbar.setBarWidth(20);
// if you want to change thumb icon that try below method
// circularSeekbar.setBitmapThumbIcon(R.mipmap.ic_fav_round);
circularSeekbar.invalidate();
circularSeekbar.setSeekBarChangeListener(new CircularSeekBar.OnSeekChangeListener() {
@Override
public void onProgressChange(CircularSeekBar view, int newProgress) {
Log.e("Seekbar_Progress", String.valueOf(view.getProgress()));
}
});
}
}
OUTPUT
注意
如果你想使用任何库检查下面的链接
关于android - 嵌入式动画,画圈和旋转图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53629762/
我正在尝试学习 Knockout 并尝试创建一个照片 uploader 。我已成功将一些图像存储在数组中。现在我想回帖。在我的 knockout 码(Javascript)中,我这样做: 我在 Jav
我正在使用 php 编写脚本。我的典型问题是如何在 mysql 中添加一个有很多替代文本和图像的问题。想象一下有机化学中具有苯结构的描述。 最有效的方法是什么?据我所知,如果我有一个图像,我可以在数据
我在两个图像之间有一个按钮,我想将按钮居中到图像高度。有人可以帮帮我吗? Entrar
下面的代码示例可以在这里查看 - http://dev.touch-akl.com/celebtrations/ 我一直在尝试做的是在 Canvas 上绘制 2 个图像(发光,然后耀斑。这些图像的链接
请检查此https://jsfiddle.net/rhbwpn19/4/ 图像预览对于第一篇帖子工作正常,但对于其他帖子则不然。 我应该在这里改变什么? function readURL(input)
我对 Canvas 有疑问。我可以用单个图像绘制 Canvas ,但我不能用单独的图像绘制每个 Canvas 。- 如果数据只有一个图像,它工作正常,但数据有多个图像,它不工作你能帮帮我吗? va
我的问题很简单。如何获取 UIImage 的扩展类型?我只能将图像作为 UIImage 而不是它的名称。图像可以是静态的,也可以从手机图库甚至文件路径中获取。如果有人可以为此提供一点帮助,将不胜感激。
我有一个包含 67 个独立路径的 SVG 图像。 是否有任何库/教程可以为每个路径创建单独的光栅图像(例如 PNG),并可能根据路径 ID 命名它们? 最佳答案 谢谢大家。我最终使用了两个答案的组合。
我想将鼠标悬停在一张图片(音乐专辑)上,然后播放一张唱片,所以我希望它向右移动并旋转一点,当它悬停时我希望它恢复正常动画片。它已经可以向右移动,但我无法让它随之旋转。我喜欢让它尽可能简单,因为我不是编
Retina iOS 设备不显示@2X 图像,它显示 1X 图像。 我正在使用 Xcode 4.2.1 Build 4D502,该应用程序的目标是 iOS 5。 我创建了一个测试应用(主/细节)并添加
我正在尝试从头开始以 Angular 实现图像 slider ,并尝试复制 w3school基于图像 slider 。 下面我尝试用 Angular 实现,谁能指导我如何使用 Angular 实现?
我正在尝试获取图像的图像数据,其中 w= 图像宽度,h = 图像高度 for (int i = x; i imageData[pos]>0) //Taking data (here is the pr
我的网页最初通过在 javascript 中动态创建图像填充了大约 1000 个缩略图。由于权限问题,我迁移到 suPHP。现在不用标准 标签本身 我正在通过这个 php 脚本进行检索 $file
我正在尝试将 python opencv 图像转换为 QPixmap。 我按照指示显示Page Link我的代码附在下面 img = cv2.imread('test.png')[:,:,::1]/2
我试图在这个 Repository 中找出语义分割数据集的 NYU-v2 . 我很难理解图像标签是如何存储的。 例如,给定以下图像: 对应的标签图片为: 现在,如果我在 OpenCV 中打开标签图像,
import java.util.Random; class svg{ public static void main(String[] args){ String f="\"
我有一张 8x8 的图片。 (位图 - 可以更改) 我想做的是能够绘制一个形状,给定一个 Path 和 Paint 对象到我的 SurfaceView 上。 目前我所能做的就是用纯色填充形状。我怎样才
要在页面上显示图像,你需要使用源属性(src)。src 指 source 。源属性的值是图像的 URL 地址。 定义图像的语法是: 在浏览器无法载入图像时,替换文本属性告诉读者她们失去的信息。此
**MMEditing是基于PyTorch的图像&视频编辑开源工具箱,支持图像和视频超分辨率(super-resolution)、图像修复(inpainting)、图像抠图(matting)、
我正在尝试通过资源文件将图像插入到我的程序中,如下所示: green.png other files 当我尝试使用 QImage 或 QPixm
我是一名优秀的程序员,十分优秀!