我有一个自定义ScrollView(扩展android.widget.ScrollView),我在我的布局中使用.我想测量此scrollview内容的总高度.getHeight()和getMeasuredHeight()不会给我正确的值(数字太高).
背景信息:我想确定用户滚动了多远.我使用onScrollChanged来获取X值,但我需要知道一个百分比,所以我需要总滚动条高度.
非常感谢!埃里克
第一件事!我不知道ViewTreeObserver.onGlobalLayoutListener.
让我问这个问题的是Android开发者文档网站上的以下通知:
下面的代码段执行以下操作:
- 获取父视图并在UI线程上发布Runnable.这可以确保父级在调用getHitRect()方法之前布局其子级.getHitRect()方法获取父级坐标中子项的命中矩形(可触摸区域).
代码片段本身是:
parentView.post(new Runnable() {
// Post in the parent's message queue to make sure the parent
// lays out its children before you call getHitRect()
@Override
public void run() {
/// do UI stuff
}
});
Run Code Online (Sandbox Code Playgroud)
(你可以看一整篇文章)
这是错误的陈述还是真的?我问,因为与使用ViewTreeObserver完成所有注册监听器/ handle-event/unregister-listener舞蹈相比,发布runnable似乎更容易,更方便:)
更新:另一个问题是为整个主题带来清晰度:如果所有这些都很好并且实际上可以发布Runnable而不是使用全局布局监听器,那么为什么我们有这个ViewTreeObserver.onGlobalLayoutListener机制呢?什么时候使用它而不是发布Runnable更好,这种方法之间有什么区别?
是否有一个总是在onResume()之后调用的回调?我需要它,因为AFAIK,在onResume()之后,布局中的每个View都被渲染了,所以我可以测量它们的尺寸.
谢谢.
我需要监听确切的一个全局布局事件,以初始设置正确的滚动位置.在搜索了一些为什么我的调用scrollTo(x,y)似乎被忽略之后,我发现只有在知道整个布局后才能以有意义的方式调用它们.所以我正在注册GlobalLayoutListener并推迟致电scrollTo().
问题是,我只想滚动一次.所以我想我可以简单地打电话removeGlobalOnLayoutListener()来停止听.这导致了例外:IllegalStateException: This ViewTreeObserver is not alive, call getViewTreeObserver() again.所以我认为我很好,如果观察者不活着它将不会发生任何事件.但遗憾的是:每当布局以某种方式改变时,我的视图都会滚动.
我当前的代码迭代看起来像这样.我可以更改什么以确保scrollToGridPos()只进行一次调用?我知道我可以mHasFired 在内部类中添加一个本地字段,但这对我来说似乎非常脏!
final ViewTreeObserver vto = mLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
scrollToGridPos(getCenterPoint(), false);
if (vto.isAlive()) {
vto.removeGlobalOnLayoutListener(this);
}
}
});
Run Code Online (Sandbox Code Playgroud) 如何在呈现活动布局后创建/绑定服务?
- 更新
我在主要活动上有两个选项卡(两个作为单独的活动),用于选项卡的数据来自服务.现在我正在绑定服务内部onCreate方法.问题是,onCreate在完成内部的所有语句之前,不会呈现布局.显示空白屏幕,直到服务绑定
我目前有一个周期性的问题,IllegalArgumentException我打电话给我Activity.startLockTask().我的应用程序安装了设备所有者应用程序,允许我的程序包自动固定自己.
下面的代码是检查以确保我的包可以锁定自己.如果它可以,那么它自己固定.
码:
if (dpm.isLockTaskPermitted(getPackageName())) {
super.startLockTask();
}
Run Code Online (Sandbox Code Playgroud)
logcat的:
java.lang.IllegalArgumentException: Invalid task, not in foreground
at android.os.Parcel.readException(Parcel.java:1544)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.ActivityManagerProxy.startLockTaskMode(ActivityManagerNative.java:5223)
at android.app.Activity.startLockTask(Activity.java:6163)
Run Code Online (Sandbox Code Playgroud)
问题是我的应用需要偶尔重启自己.因此,我们取消固定,完成活动并使用新任务重新启动它,然后退出我们的流程.当活动恢复时,它试图固定自己 - 有时它有效 - 有时它不会.我相信我们如何重新启动可能是抛出异常的原因,但它应该无关紧要,因为新活动是在前台并且是IS重点.
一旦活动失败,它就会继续失败,只要它尝试:如果我坐在那里尝试每5秒固定一次任务,它每次都会继续失败.我试着钉扎onCreate,onWindowFocusChanged,onResume,和onStart.
有谁知道问题可能是什么?
供参考:
8853行:https://android.googlesource.com/platform/frameworks/base/+/android-5.0.2_r1/services/core/java/com/android/server/am/ActivityManagerService.java
是否存在向后兼容的方式来确定视图是否布局?View有isLaidOut,但它是API 19.我目前使用if(view.getWidth() + view.getHeight() > 0),但它看起来不像一个稳定和干净的方式来做到这一点.我知道OnGlobalLayoutListener,但我想知道现在是否有一个观点.
我正在使用GridView来显示一些图像并且我遇到了问题,因为onClickListener不适用于第一个图像.我在SO处发现了一些其他问题同样的问题,但我不喜欢他们的"正确答案",因为他们大多采用相同的方法:
基本上,每次调用getview时都要实例化视图.这对于性能很糟糕,并且它们可能会在许多设备中面临内存不足的问题.
在我的例子中,我在GridView中显示位于assets文件夹中的子文件夹内的图像.
我的原始代码带有"第一项"问题(实际上,我的原始代码实现了视图模式,但这个更简单并面临同样的问题):
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(_activity);
} else {
imageView = (ImageView) convertView;
}
// get screen dimensions
AssetManager assetManager = _activity.getAssets();
InputStream assetIn = null;
try {
assetIn = assetManager.open(_assets_subdir + File.separator + _filePaths.get(position));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap image = BitmapFactory.decodeStream(assetIn);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
imageView.setImageBitmap(image);
// image view click …Run Code Online (Sandbox Code Playgroud) 我使用Universal Image Loader库加载一组图像和TouchImageView以允许缩放.我决定用毕加索取代Universal Image Loader.一切都很好,除了现在图像缩放到比图像稍大的帧.
@Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = inflater.inflate(R.layout.item_pager_image, view, false);
assert imageLayout != null;
TouchImageView imageView = (TouchImageView) imageLayout.findViewById(R.id.image);
final ProgressBar spinner = (ProgressBar) imageLayout.findViewById(R.id.loading);
spinner.setVisibility(View.INVISIBLE);
Picasso.with(getApplicationContext()).setIndicatorsEnabled(false);
Picasso.with(getApplicationContext()).load(images[position]).into(imageView,new Callback() {
@Override
public void onSuccess() {
spinner.setVisibility(View.GONE);
}
@Override
public void onError() {
}
});
view.addView(imageLayout, 0);
return imageLayout;
Run Code Online (Sandbox Code Playgroud)
为此,我几个小时就一直在挣扎.这是TouchImageView与Picasso有关的问题吗?任何帮助都会很明显.谢谢.
嗨,我在RelativeLayout中有一个ImageView,现在我怎样才能在屏幕上获得imageview的X和Y位置?
我试过了
getLocationOnScreen
log(mPhoto.getLeft());
log(mPhoto.getScrollX());
log(mPhoto.getX());
log(mPhoto.getTranslationX());
Run Code Online (Sandbox Code Playgroud)
但他们都返回0.
在将imageview设置为居中之后调用上述函数
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(mFaceWidth, mFaceHeight);
lp1.addRule(RelativeLayout.CENTER_HORIZONTAL);
lp1.addRule(RelativeLayout.CENTER_VERTICAL);
mPhoto.setLayoutParams(lp1);
mPhoto.requestLayout();
Run Code Online (Sandbox Code Playgroud) 我正在使用 Camera2 API 构建自定义相机。到目前为止,除了预览有时会失真之外,相机工作得很好。假设我连续打开相机 7 次。所有尝试均成功,但第 8 次相机预览失真。看起来它使用宽度作为高度,反之亦然。
我的代码基于camera2 的Google 示例实现,可以在此处找到。有趣的是,即使是 Google 示例实现有时也会出现这种扭曲的预览。我尝试修改 AutoFitTextureView 但没有成功。我目前正在使用 Google 再次提供的 AutoFitTextureView.java 。
可以在此处找到与此类似的帖子。然而,所提出的修复方案并没有解决问题。
我可以通过更改 setUpCameraOutputs 方法中的以下内容来重现该问题:
mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
Run Code Online (Sandbox Code Playgroud)
到:
mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Run Code Online (Sandbox Code Playgroud)
另一个奇怪的事情是,每当预览失真时,您只需按主页按钮,应用程序就会进入 onPause() 并再次打开应用程序,以便调用 onResume() ,每次预览都是完美的。
这里有人遇到过这个问题并找到解决办法吗?
提前致谢
android ×11
android-ui ×1
callback ×1
camera2 ×1
distortion ×1
gridview ×1
imageview ×1
picasso ×1
preview ×1
scroll ×1
scrollview ×1