- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在修复某人的 Android 应用程序。它最初是为 2.1 制作的,我正在努力让它工作到 4.0+。不幸的是,制作该应用程序的人不在身边,所以我只能使用他的代码。
该应用程序实现了自定义 slider 、水平 slider 和垂直 slider 。我固定了垂直 slider ,但我无法让水平 slider 工作。它没有调用 onDraw()
:当 View 加载时,onDraw()
被调用并且我看到我的两个 slider 都已初始化,然后当我移动我的水平 slider 时它移动并调用 onDraw()
一次,但它再也不会调用它,这与调用它的垂直 slider 不同。
代码如下:
public class PanSeekBar extends RelativeLayout {
private RelativeLayout layout1;
public ImageView track;
public ImageView thumb;
public boolean initialized = false;
public int thumbDownPosX = 0;
public int thumbDownPosY = 0;
public int thumbLeft = 0;
public int thumbTop = 0;
public int thumbRight = 0;
public int thumbBottom = 0;
private int max = 100;
public boolean touched = false;
public PanSeekBar(Context context) {
super(context);
initialize(context);
// TODO Auto-generated constructor stub
}// End of PanSeekBar Constructor
private void initialize(Context context) {
Log.d("initialize (PanSeekBar)", "initialize");
setWillNotDraw(false);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view1 = inflater.inflate(R.layout.pan_seekbar, this);
layout1 = (RelativeLayout) view1.findViewById(R.id.ps_layout1);
track = (ImageView) layout1.findViewById(R.id.ps_track);
thumb = (ImageView) layout1.findViewById(R.id.ps_thumb);
thumb.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
initialized = true;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("onTouch (PanSeekBar)", "Action Down");
thumbDownPosX = (int) event.getX();
thumbDownPosY = (int) event.getY();
thumbLeft = thumb.getLeft();
thumbTop = thumb.getTop();
thumbRight = thumb.getRight();
thumbBottom = thumb.getBottom();
touched = true;
break;
case MotionEvent.ACTION_MOVE:
// Log.d("onTouch (PanSeekBar)", "Action Move");
int left = (int) (thumb.getLeft() + event.getX() - thumbDownPosX);
if (left < 0) {
left = 0;
Log.d("onTouch (PanSeekBar)", "left < 0: " + left);
} else if (left >= track.getWidth() - thumb.getWidth()) {
left = track.getWidth() - thumb.getWidth();
Log.d("onTouch (PanSeekBar)",
"left >= track.getWidth(): " + left);
}
int top = thumb.getTop();
int right = left + thumb.getWidth();
int bottom = top + thumb.getHeight();
thumbLeft = left;
thumbTop = top;
thumbRight = right;
thumbBottom = bottom;
Log.d("onTouch (PanSeekBar)",
"Action Move -- thumb layout: " + thumbLeft + ", "
+ thumbTop + ", " + thumbRight + ", "
+ thumbBottom);
layout1.invalidate();
// thumb.invalidate();
break;
case MotionEvent.ACTION_UP:
Log.d("onTouch (PanSeekBar)", "Action Up");
touched = false;
break;
}// End of switch
return true;
}// End of onTouch
});
}// End of initialize
@Override
protected void onDraw(Canvas canvas) {
Log.d("onDraw (PanSeekBar)", "onDraw");
super.onDraw(canvas);
if (initialized) {
thumb.layout(thumbLeft, thumbTop, thumbRight, thumbBottom);
Log.d("onDraw (PanSeekBar)", "thumb layout: " + thumbLeft + ", "
+ thumbTop + ", " + thumbRight + ", " + thumbBottom);
}
}// End of onDraw
}// End of PanSeekBar
这是有效的垂直 slider 代码:
public class MySeekBar extends RelativeLayout {
private RelativeLayout layout1;
public ImageView track;
public ImageView thumb;
private MyToast toast;
private MyToast toast2;
private MyToast toast3;
private int globalMaxValue;
private int globalProgress;
private boolean initialized = false;
public int thumbDownPosX = 0;
public int thumbDownPosY = 0;
public int thumbLeft = 0;
public int thumbTop = 0;
public int thumbRight = 0;
public int thumbBottom = 0;
private int globalSetProgress = 0;
private int globalConfigType = 1;
// Margin top in custom_seekbar.xml
private int marginTop = 20;
public boolean touched = false;
public MySeekBar(Context context) {
super(context);
// TODO Auto-generated constructor stub
initialize(context);
}// End of MySeekBar
public void initialize(Context context) {
Log.d("initialize (MySeekBar)", "initialize");
setWillNotDraw(false);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view1 = inflater.inflate(R.layout.custom_seekbar, this);
layout1 = (RelativeLayout) view1.findViewById(R.id.al_cs_layout1);
track = (ImageView) layout1.findViewById(R.id.cs_track);
thumb = (ImageView) layout1.findViewById(R.id.cs_thumb);
// Gets marginTop
MarginLayoutParams params = (MarginLayoutParams) track
.getLayoutParams();
Log.d("initialize (MySeekBar)", "current margintop = " + marginTop);
marginTop = params.topMargin;
Log.d("initialize (MySeekBar)", "new margintop = " + marginTop);
// int marginTopPixelSize = params.topMargin;
// Log.d("initialize (MySeekBar)","debug = "+marginTopPixelSize);
// Jared
// When creating MyToast, setting width causes issues.
toast = new MyToast(context);
toast.setText("");
toast.setBackgroundColor(Color.LTGRAY);
toast.setTextColor(Color.BLACK);
toast.setPadding(1, 1, 1, 1);
toast.setVisibility(View.INVISIBLE);
toast.setTextSize(10f);
// toast.setWidth(40);
toast2 = new MyToast(context);
toast2.setTextSize(12f);
toast2.setTextColor(Color.rgb(192, 255, 3));
// toast2.setWidth(40);
toast2.setPadding(10, 1, 1, 1);
// toast2.setBackgroundColor(Color.BLACK);
toast2.setVisibility(View.INVISIBLE);
toast3 = new MyToast(context);
toast3.setText("CH");
toast3.setTextSize(15f);
toast3.setTextColor(Color.rgb(192, 255, 3));
// toast3.setWidth(40);
toast3.setPadding(1, 1, 1, 1);
layout1.addView(toast);
layout1.addView(toast2);
layout1.addView(toast3);
thumb.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
initialized = true;
// 0=down 1=up 2=move
// Log.d("onTouch (MySeekBar)",
// Integer.toString(event.getAction()));
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("onTouch (MySeekBar)", "Action Down");
thumbDownPosX = (int) event.getX();
thumbDownPosY = (int) event.getY();
// Position of thumb touched. Irrelevant to scale
// Log.d("onTouch (NewSeekBar)","thumbDownPosX "+thumbDownPosX+" thumbDownPosY "+thumbDownPosY);
thumbLeft = thumb.getLeft();
thumbTop = thumb.getTop();
thumbRight = thumb.getRight();
thumbBottom = thumb.getBottom();
touched = true;
toast2.setVisibility(View.INVISIBLE);
toast3.setVisibility(View.INVISIBLE);
toast.setVisibility(View.VISIBLE);
// Location/size of the thumb button
// Log.d("onTouch (NewSeekBar)","thumbLeft "+thumbLeft+" thumbRight "+thumbRight+" thumbTop "+thumbTop+" thumbBottom "+thumbBottom);
break;
case MotionEvent.ACTION_MOVE:
// Log.d("onTouch (MySeekBar)", "Action Move");
int thumbHeight = thumb.getHeight();
int thumbWidth = thumb.getWidth();
int trackWidth = track.getWidth();
int trackHeight = track.getHeight();
// Location/size of the thumb button and track
// Log.d("onTouch (NewSeekBar)","thumbHeight "+thumbHeight+" thumbWidth "+thumbWidth+" trackWidth "+trackWidth+" trackHeight "+trackHeight);
int top = (int) (thumb.getTop() + event.getY() - thumbDownPosY);
Log.d("onTouch (NewSeekBar)", "top " + top);
// Top border
if (top < marginTop) {
top = marginTop;
Log.d("onTouch (NewSeekBar)", "top < marginTop " + top);
} else if (top >= trackHeight - thumbHeight + marginTop) {
top = trackHeight - thumbHeight + marginTop;
Log.d("onTouch (NewSeekBar)", "top >= trackHeight "
+ top);
}
thumbLeft = thumb.getLeft();
;
thumbTop = top;
thumbRight = thumbLeft + thumbWidth;
thumbBottom = top + thumbHeight;
// Log.d("onTouch (MySeekBar)",
// "thumbTop: "+thumbTop+" thumbBottom: "+thumbBottom);
int value = getProgress();
Log.d("onTouch (NewSeekBar)", "getProgress(): " + value);
// setdBText(value);
// Log.d("onTouch (MySeekBar)", "value: "+value);
setProgress(value);
// toast.setText(String.valueOf(temp));
// toast2.setText(String.valueOf(temp));
layout1.invalidate();
break;
case MotionEvent.ACTION_UP:
Log.d("onTouch (MySeekBar)", "Action Up");
toast.setVisibility(View.INVISIBLE);
toast2.setVisibility(View.VISIBLE);
toast3.setVisibility(View.VISIBLE);
touched = false;
break;
}// End of switch
return true;
}// End of onTouch
});
}// End of initialize
@Override
protected void onDraw(Canvas canvas) {
Log.d("onDraw (MySeekBar)", "onDraw");
super.onDraw(canvas);
if (initialized) {
thumb.layout(thumbLeft, thumbTop, thumbRight, thumbBottom);
Log.d("onDraw (MySeekBar)", "thumb layout: " + thumbLeft + ", "
+ thumbTop + ", " + thumbRight + ", " + thumbBottom);
int top = thumbTop - marginTop;
int left = thumbLeft + 4;
// toast.layout(left, top, left + toast.getWidth(), top +
// toast.getHeight());
top = thumbTop + thumb.getHeight() / 2 - toast2.getHeight() / 2 + 1;
left = thumbLeft;
toast2.layout(left, top, left + toast2.getWidth(),
top + toast2.getHeight());
}
}// End of onDraw
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/test_layout">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<com.networksound.Mixer3.NewSeekBar
android:id="@+id/newSeekBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</com.networksound.Mixer3.NewSeekBar>
<com.networksound.Mixer3.NewSeekBar
android:id="@+id/newSeekBar2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</com.networksound.Mixer3.NewSeekBar>
<com.networksound.Mixer3.MySeekBar
android:id="@+id/mySeekBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</com.networksound.Mixer3.MySeekBar>
<com.networksound.Mixer3.MySeekBar
android:id="@+id/mySeekBar2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</com.networksound.Mixer3.MySeekBar>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.networksound.Mixer3.PanSeekBar
android:id="@+id/panSeekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.networksound.Mixer3.PanSeekBar>
<com.networksound.Mixer3.PanSeekBar
android:id="@+id/panSeekBar2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</com.networksound.Mixer3.PanSeekBar>
</LinearLayout>
</LinearLayout>
最佳答案
如果你正在扩展一个 ViewGroup
,你应该覆盖 dispatchDraw()
而不是 onDraw()
,或者在构造函数中调用setWillNotDraw(false)
。有一些讨论here .
关于android - onDraw() 未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15394450/
我找到了 this excellent question and answer它以 x/y(加上 center x/y 和 degrees/radians)开始并计算旋转- 到 x'/y'。这个计算很
全部: 我已经创建了一个 Windows 窗体和一个按钮。在另一个线程中,我试图更改按钮的文本,但它崩溃了;但是如果我尝试更改按钮的颜色,它肯定会成功。我认为如果您更改任何 Windows 窗体控件属
本网站的另一个问题已证实,C 中没有缩写的字面后缀,并且可以执行以下操作: short Number = (short)1; 但是转换它和不这样做有什么区别: short Number = 1; 您使
我有下表: ID (int) EMAIL (varchar(50)) CAMPAIGNID (int) isSubscribe (bit) isActionByUser (bit) 此表存储了用户对事
也就是说,无需触发Javascript事件即可改变的属性,如何保留我手动选中或取消选中的复选框的状态,然后复制到另一个地方? 运行下面的代码片段并选中或取消选中其中的一些,然后点击“复制”: $('#
我在网上找到的所有关于递增指针导致段错误的示例都涉及指针的取消引用 - 如果我只想递增它(例如在 for 循环的末尾)并且我不在乎它是否最终进入无效内存,因为我不会再使用它。例如,在这个程序中,每次迭
我有一个 Spring MVC REST 服务,它使用 XStream 将消息与 XML 相互转换。 有什么方法可以将请求和响应中的 xml(即正文)打印到普通的 log4j 记录器? 在 Contr
做我的任务有一个很大的挑战,那就是做相互依赖的任务我在这张照片中说的。假设我们有两个任务 A 和 B,执行子任务 A1、A2 和 B1、B2,假设任务 B 依赖于 A。 要理想地执行任务 B,您应该执
通过阅读该网站上的几个答案,我了解到 CoInitialize(Ex) should be called by the creator of a thread 。然后,在该线程中运行的任何代码都可以使
这个问题已经困扰我一段时间了。我以前从未真正使用过 ListViews,也没有使用过 FirebaseListAdapters。我想做的就是通过显示 id 和用户位置来启动列表的基础,但由于某种原因,
我很难解释这两个(看似简单)句子的含义: “受检异常由编译器在编译时检查” 这是什么意思?编译器检查是否捕获了所有已检查的异常(在代码中抛出)? “未经检查的异常在运行时检查,而不是编译时” 这句话中
我有一个包含排除子字符串的文本文件,我想迭代该文件以检查并返回不带排除子字符串的输入项。 这里我使用 python 2.4,因此下面的代码可以实现此目的,因为 with open 和 any 不起作用
Spring 的缓存框架能否了解请求上下文的身份验证状态,或者更容易推出自己的缓存解决方案? 最佳答案 尽管我发现这个用例 super 奇怪,但您可以为几乎任何与 SpEL 配合使用的内容设置缓存条件
我有以下函数模板: template HeldAs* duplicate(MostDerived *original, HeldAs *held) { // error checking omi
如果我的应用程序具有设备管理员/设备所有者权限(未获得 root 权限),我如何才能从我的应用程序中终止(或阻止启动)另一个应用程序? 最佳答案 设备所有者可以阻止应用程序: DevicePolicy
非常简单的问题,但我似乎无法让它正常工作。 我有一个组件,其中有一些 XSLT(用于导航)。它通过 XSLT TBB 使用 XSLT Mediator 发布。 发布后
我正在将一个对象拖动到一个可拖放的对象内,该对象也是可拖动的。放置对象后,它会嵌套在可放置对象内。同样,如果我将对象拖到可放置的外部,它就不再嵌套。 但是,如果我经常拖入和拖出可放置对象,则可拖动对象
我正在尝试为按钮和弹出窗口等多个指令实现“取消选择”功能。也就是说,我希望当用户单击不属于指令模板一部分的元素时触发我的函数。目前,我正在使用以下 JQuery 代码: $('body').click
我从 this question 得到了下面的代码,该脚本用于在 Google tasks 上更改 iframe[src="about:blank"] 内的 CSS使用 Chrome 扩展 Tempe
我有一些 @Mock 对象,但没有指定在该对象上调用方法的返回值。该方法返回 int (不是 Integer)。我很惊讶地发现 Mockito 没有抛出 NPE 并返回 0。这是预期的行为吗? 例如:
我是一名优秀的程序员,十分优秀!