Android编程中a View
和a有什么区别ViewGroup
?
我们已经发现了几种由后端日志记录监控报告的此类崩溃案例.似乎崩溃与特定的UX失败无关.从报告中,没有迹象表明我们自己的课程如何参与(没有任何课程名称的迹象).以下是典型崩溃的示例:
java.lang.NullPointerException: Attempt to read from field 'int android.view.View.mViewFlags' on a null object reference
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3357)
at android.view.View.updateDisplayListIfDirty(View.java:14288)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528)
at android.view.View.updateDisplayListIfDirty(View.java:14253)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528)
at android.view.View.updateDisplayListIfDirty(View.java:14253)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528)
at android.view.View.updateDisplayListIfDirty(View.java:14253)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528)
at android.view.View.updateDisplayListIfDirty(View.java:14253)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528)
at android.view.View.updateDisplayListIfDirty(View.java:14253)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528)
at android.view.View.updateDisplayListIfDirty(View.java:14253)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528)
at android.view.View.updateDisplayListIfDirty(View.java:14253)
at android.view.View.getDisplayList(View.java:14315)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3549)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3528) …
Run Code Online (Sandbox Code Playgroud) 我有一个ListView,里面有一些可聚焦的组件(主要是EditText
s).是的,我知道这不是完全推荐的,但总的来说,几乎所有东西都工作正常,重点放在必须去的地方(我需要进行一些调整代码).无论如何,我的问题是,当用手指滚动列表然后在显示IME键盘时突然使用轨迹球时,存在一种奇怪的竞争条件.有些东西必须超出范围并得到回收,此时该offsetRectBetweenParentAndChild()
方法必须启动并抛出IllegalArgumentException
.
问题是这个异常被抛出我可以插入try/catch的任何块之外(据我所知).所以这个问题有两个有效的解决方案:
ViewGroup
这些方法,但这两种offset*
方法被标记为final.堆栈跟踪:
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): FATAL EXCEPTION: main
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): java.lang.IllegalArgumentException: parameter must be a descendant of this view
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.view.ViewGroup.offsetRectBetweenParentAndChild(ViewGroup.java:2633)
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.view.ViewGroup.offsetDescendantRectToMyCoords(ViewGroup.java:2570)
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.view.ViewRoot.scrollToRectOrFocus(ViewRoot.java:1624)
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.view.ViewRoot.draw(ViewRoot.java:1357)
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.view.ViewRoot.performTraversals(ViewRoot.java:1258)
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.os.Handler.dispatchMessage(Handler.java:99)
08-17 18:23:09.825: ERROR/AndroidRuntime(1608): at android.os.Looper.loop(Looper.java:130)
08-17 …
Run Code Online (Sandbox Code Playgroud) public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TableView tv = new TableView(this);
tv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
setContentView(tv);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
public class TableView extends ViewGroup {
private Paint oval;
private RectF rect;
public TableView(Context context) {
super(context);
oval= new Paint(Paint.ANTI_ALIAS_FLAG);
oval.setColor(Color.GREEN);
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawOval(rect , oval);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int wspec = MeasureSpec.makeMeasureSpec( …
Run Code Online (Sandbox Code Playgroud) 我如何实现固定的宽高比View
?我想要一个宽高比为1:1的物品GridView
.我认为将孩子分类比把它分类更好GridView
?
编辑:我认为这需要以编程方式完成,这没问题.另外,我不想限制大小,只限制宽高比.
有没有办法从视图中获取ViewGroup?我正在尝试创建自定义数组适配器,它需要viewgroup
我正在为Android开发游戏.为了帮助实现它,我的想法是创建一个视图的子类.然后我会插入此类的几个实例作为主视图的子项.每个实例都会处理它被按下的时间(通过OnTouchListener).
我现在遇到的问题是如何遍历所有这些子视图,以便我可以读取它们的状态并处理它们?(即当他们都达到某种状态时应该发生的事情).
或者,是否有更好的方法可以在屏幕上显示多个响应触摸的对象以及我可以检查其状态?
为什么RelativeLayout
替换为ConstraintLayout
android空活动的默认布局文件.我需要知道为什么要使用ConstraintLayout
它,它为我们提供了什么其他好处.
我在使用标签<include>
和<merge>
ConstraintLayout内部时遇到问题.
我想创建一个平面视图层次结构(因此Constraints),但仍然有可重用的元素.所以我<include>
在我的布局和<merge>
包含的布局中使用以避免嵌套布局(特别是避免嵌套的ConstraintLayouts)
所以我写了这样的:父布局
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/review_1"
layout="@layout/view_movie_note"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/review_2"/>
<include
layout="@layout/view_movie_note"
android:id="@+id/review_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginLeft="7dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/review_1"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
这个view_movie_note:
<merge>
<TextView
android:id="@+id/note_origin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginStart="5dp"
app:layout_constraintStart_toStartOf="@+id/cardView2"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="5dp" />
<android.support.v7.widget.CardView
android:id="@+id/five_star_view_container"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="10dp"
android:elevation="3dp"
app:cardUseCompatPadding="true"
app:contentPaddingTop="22dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_min="52dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/note_origin">
<FiveStarsView
android:id="@+id/five_star_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="@+id/cardView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:cardBackgroundColor="@color/colorPrimary"
app:contentPaddingLeft="15dp"
app:contentPaddingRight="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/note_origin">
<TextView
android:id="@+id/grade" …
Run Code Online (Sandbox Code Playgroud) 我遇到了一个令我难过的问题,我希望有人可以给我一些指示.
我正在使用一个使用自定义ViewGroup的应用程序(实际上是一个包含RelativeLayout的FrameLayout)来呈现事件日历.日历中的事件表示为视图,其大小根据事件的持续时间和包含视图的大小而定.
我遇到了调整包含FrameLayout大小时发生的问题.当前实现将删除表示事件的所有视图,并尝试添加新事件并根据FrameLayout的当前大小计算其大小.这项工作是通过View的onSizeChanged()方法触发的,该方法在FrameLayout中被覆盖.
调整视图大小时,将执行此代码并更新视图,但是,它们实际上都不会在屏幕上呈现... FrameLayout中包含的视图根本不可见.如果我在hierarchyviewer工具中加载视图,它们是视图树的一部分,并在概述中列出它们应该位于的位置,但它们不会显示.(请注意,视图在FrameLayout的初始渲染中是可见的......只有在调整大小后它们才会消失.)
看来调整大小期间的事件顺序如下:
onMeasure()
onMeasure()
onSizeChanged()
onLayout()
Run Code Online (Sandbox Code Playgroud)
重置视图后调用requestLayout()(在onSizeChanged()内)似乎没有任何效果.但是,如果在调用requestLayout()之前导致一些延迟,则视图将变为可见.我可以通过生成一个线程和休眠来创建这个延迟,或者通过创建一个虚拟按钮来简单地调用requestLayout()并在调整大小后自己调整它,或者甚至在onSizeChanged()的末尾放置这个丑陋的黑客:
post(new Runnable() {
public void run() {
requestLayout();
}
});
Run Code Online (Sandbox Code Playgroud)
当我使用这个hack时,包含的视图是可见的,事件的顺序如下:
onMeasure()
onMeasure()
onSizeChanged()
onLayout()
onMeasure()
onMeasure()
onLayout()
Run Code Online (Sandbox Code Playgroud)
因此,似乎强制第二个度量传递(在视图树被修改之后)使得包含的视图应该是可见的.为什么延迟对requestLayout()的调用对我来说这是一个谜.
谁能提供任何关于我做错的指示?
我意识到,如果不查看一些代码,这有点难以理解,因此我创建了一个小型示例应用程序,它展示了我的问题并使其在Github上可用:
https://github.com/MichaelSims/ViewGroupResizeTest
我上面提到的hack致力于一个单独的分支:
https://github.com/MichaelSims/ViewGroupResizeTest/tree/post-runnable-hack
如果我能提供任何其他信息,请提前通知我并提前致谢.
android ×10
viewgroup ×10
view ×5
aspect-ratio ×1
custom-view ×1
java ×1
layout ×1
rendering ×1
resize ×1
viewroot ×1