- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我希望实现某种“ Canvas ”,您可以在其中将 X 数量的 TextViews/Links 放置在“随机位置”(如下图所示)。然后,您将能够连续向左或向右滚动此“ Canvas ” View ,并且该 View 将重复/呈圆形(有点像 HTML 选取框,只是您正在手动滚动)。在最简单的情况下,我只是希望进行水平滚动——但是一个更“复杂的情况”的例子是你可以做“球体滚动”的地方——参见下面来自 Appy Geek 的例子。 (现在我只对水平滚动感兴趣)
来自 Appy Geek 的示例:
最佳答案
好吧,这会让你开始,我已经使用两种方法(即通过扩展 View
和 ViewGroup
)实现了一个简单的标签云,它一直在旋转。您可以在自定义 ViewGroup
中使用此逻辑,从而相应地定位其 View 。之后在该布局中添加可点击的 TextView
并处理触摸事件。
最终结果(当然是旋转的,仔细看):
下面的代码可以改进很多东西。
通过扩展 ViewGroup
:
将其放入 xml 布局中:
<com.vj.tagcloud.TagCloudLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</com.vj.tagcloud.TagCloudLayout>
TagCloudLayout
类:
import java.util.Random;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class TagCloudLayout extends ViewGroup {
final Random mRandom = new Random();
private float mRotateAngle;
private Handler mHandler = new Handler();
private float rotateAngleDegree;
public TagCloudLayout(Context context) {
super(context);
}
public TagCloudLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TagCloudLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final float radius = Math.min(getMeasuredWidth(), getMeasuredHeight()) / 2F;
float halfWidth = getMeasuredWidth() / 2F;
float halfHeight = getMeasuredHeight() / 2F;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
float sinTheta = (float) Math.sin(lp.theta);
float x = (int) (radius * Math.cos(lp.fi + mRotateAngle)
* sinTheta);
if (child instanceof TextView) {
((TextView) child)
.setTextSize(15 * ((radius - x) / radius) + 10);
}
measureChild(child, widthMeasureSpec, heightMeasureSpec);
// http://en.wikipedia.org/wiki/Spherical_coordinates
lp.x = (int) ((halfWidth + radius * Math.sin(lp.fi + mRotateAngle)
* sinTheta) - /* for balancing on x-axis */(child
.getMeasuredWidth() / 2F));
lp.y = (int) (halfHeight + radius * Math.cos(lp.theta)-/* for balancing on y-axis */(child
.getMeasuredHeight() / 2F));
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
rotateAngleDegree += 5;
mRotateAngle = (float) Math.toRadians(rotateAngleDegree);
requestLayout();
mHandler.postDelayed(this, 40);
}
}, 40);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacksAndMessages(null);
}
@Override
public void addView(View child, int index,
android.view.ViewGroup.LayoutParams params) {
super.addView(child, index, params);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
lp.fi = (float) Math.toRadians(mRandom.nextInt(360));
lp.theta = (float) Math.toRadians(mRandom.nextInt(360));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y
+ child.getMeasuredHeight());
}
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p.width, p.height);
}
public static class LayoutParams extends ViewGroup.LayoutParams {
int x;
int y;
float fi, theta;
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LayoutParams(int w, int h) {
super(w, h);
}
}
}
通过扩展 View
:
将其放入 xml 布局中:
<com.vj.wordtap.TagCloud
android:layout_width="match_parent"
android:layout_height="match_parent" />
这是在 java 代码中:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
public class TagCloud extends View {
private List<String> mItems = new ArrayList<String>();
private List<Angles> mAngles = new ArrayList<Angles>();
private Camera mCamera = new Camera();
private TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private Handler mHandler = new Handler();
private float mRotateAngle;
private float rotateAngleDegree;
public static class Angles {
float fi, theta;
}
public TagCloud(Context context) {
super(context);
init();
}
public TagCloud(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TagCloud(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
List<String> items = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
items.add("item:" + i);
}
setItems(items);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(canvas.getWidth() / 2F, canvas.getHeight() / 2F);
mTextPaint.setColor(Color.BLACK);
final float radius = 100;
mCamera.setLocation(0, 0, -100);
for (int i = 0; i < mItems.size(); i++) {
String item = mItems.get(i);
Angles xyz = mAngles.get(i);
mCamera.save();
canvas.save();
float sinTheta = (float) Math.sin(xyz.theta);
float x = (float) (radius * Math.cos(xyz.fi + mRotateAngle) * sinTheta);
float y = (float) (radius * Math.sin(xyz.fi + mRotateAngle) * sinTheta);
float z = (float) (radius * Math.cos(xyz.theta));
// mapping coordinates with Android's coordinates
// http://en.wikipedia.org/wiki/Spherical_coordinates
mCamera.translate(y, z, x);
mCamera.applyToCanvas(canvas);
// http://en.wikipedia.org/wiki/Spherical_coordinates
// set size based on x-Axis that is coming towards us
mTextPaint.setTextSize(20 * ((100 - x) / 100) + 10);
canvas.drawText(item, 0, 0, mTextPaint);
mCamera.restore();
canvas.restore();
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
rotateAngleDegree += 5;
mRotateAngle = (float) Math.toRadians(rotateAngleDegree);
invalidate();
mHandler.postDelayed(this, 40);
}
}, 40);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacksAndMessages(null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void setItems(List<String> items) {
mItems = items;
final Random ran = new Random();
final List<Angles> xyzList = mAngles;
xyzList.clear();
for (int i = 0; i < items.size(); i++) {
Angles xyz = new Angles();
float fi = (float) Math.toRadians(ran.nextInt(360));
xyz.fi = fi;
float theta = (float) Math.toRadians(ran.nextInt(360));
xyz.theta = theta;
xyzList.add(xyz);
}
}
}
关于android - 如何为文本创建 3D 圆形 ScrollView ? (如 Appy Geek 中所见),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20193168/
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我试图用这种形式简单地获取数字 28 integer+space+integer+integer+space+integer我试过这个正则表达式 \\s\\d\\d\\s 但我得到了两个数字11 和
最近一直在学习D语言。我一直对运行时感到困惑。 从我能收集到的关于它的信息中,(这不是很多)我知道它是一种有助于 D 的一些特性的运行时。像垃圾收集一样,它与您自己的程序一起运行。但是既然 D 是编译
想问一下这两个正则表达式有区别吗? \d\d\d 与 \d{3} 我已经在我的本地机器上使用 Java 和 Windows 操作系统对此进行了测试,两者都工作正常并且结果相同。但是,当在 linux
我正在学习 Go,而且我坚持使用 Go 之旅(exercise-stringer.go:https://tour.golang.org/methods/7)。 这是一些代码: type IPAddr
我在Java正则表达式中发现了一段令我困惑的代码: Pattern.compile( "J.*\\d[0-35-9]-\\d\\d-\\d\\d" ); 要编译的字符串是: String string
我在 ruby 代码上偶然发现了这个。我知道\d{4})\/(\d\d)\/(\d\d)\/(.*)/是什么意思,但是\1-\2-\3-\4 是什么意思? 最佳答案 \1-\2-\3-\4 是 b
我一直在努力解决这个问题,这让我很恼火。我了解 D 运行时库。它是什么,它做什么。我也明白你可以在没有它的情况下编译 D 应用程序。就像 XoMB 所做的那样。好吧,XoMB 定义了自己的运行时,但是
我有两个列表列表,子列表代表路径。我想找到所有路径。 List> pathList1 List> pathList2 当然是天真的解决方案: List> result = new ArrayList>
我需要使用 Regex 格式化一个字符串,该字符串包含数字、字母 a-z 和 A-Z,同时还包含破折号和空格。 从用户输入我有02-219 8 53 24 输出应该是022 198 53 24 我正在
目标是达到与this C++ example相同的效果: 避免创建临时文件。我曾尝试将 C++ 示例翻译为 D,但没有成功。我也尝试过不同的方法。 import std.datetime : benc
tl;dr:你好吗perfect forwarding在 D? 该链接有一个很好的解释,但例如,假设我有这个方法: void foo(T)(in int a, out int b, ref int c
有什么方法可以在 D 中使用abstract auto 函数吗? 如果我声明一个类如下: class MyClass { abstract auto foo(); } 我收到以下错误: mai
有没有人为内存中重叠的数组切片实现交集?算法在没有重叠时返回 []。 当 pretty-print (使用重叠缩进)内存中重叠的数组切片时,我想要这个。 最佳答案 如果您确定它们是数组,那么只需取 p
我已经开始学习 D,但我在使用 Andrei Alexandrescu 所著的 The D Programming Language 一书中提供的示例时遇到了一些麻烦。由于 int 和 ulong 类
如何创建一个不可变的类? 我的目标是创建一个实例始终不可变的类。现在我只是用不可变的方法和构造函数创建了一个“可变”类。我将其称为 mData,m 表示可变。然后我创建一个别名 alias immut
不久前我买了《The D Programming Language》。好书,很有教育意义。但是,我在尝试编译书中列出的语言功能时遇到了麻烦:扩展函数。 在这本书中,Andrei 写了任何可以像这样调用
我在 D http://www.digitalmars.com/d/2.0/lazy-evaluation.html 中找到了函数参数的惰性求值示例 我想知道如何在 D 中实现可能的无限数据结构,就像
这个问题在这里已经有了答案: 12 年前关闭。 Possible Duplicate: Could anyone explain these undefined behaviors (i = i++
当前是否可以跨模块扫描/查询/迭代具有某些属性的所有函数(或类)? 例如: source/packageA/something.d: @sillyWalk(10) void doSomething()
我是一名优秀的程序员,十分优秀!