‘壹’ android怎样取得ViewGroup里面的所有ImageView
希望对你银迟有帮助!LinearLayoutlayout=newLinearLayout(this); intcount=layout.getChildCount(); ListallImageViews=newArrayList(); for(intindex=0;indexViewchild=layout.getChildAt(index); allImageViews.add((ImageView)child);}LZ你说的是这样吗?ViewGroup是所有Layout的抽象父尺搏中类陵山,所以这里LinearLayout作为一个示例。
‘贰’ android 怎样取得ViewGroup里面的所有ImageView
LinearLayout layout = new LinearLayout(this);
int count = layout.getChildCount();
List<ImageView> allImageViews = new ArrayList<ImageView>();
for(int index = 0 ; index < count; index ++){
View child = layout.getChildAt(index);
if(child instanceof ImageView)
allImageViews.add((ImageView) child);
}
LZ你说的是这瞎碧枝样吗?ViewGroup是所有Layout的抽象父类,磨敏所以这里LinearLayout 作慧游为一个示例。
‘叁’ android开发 BaseAdapter中getView()里的ViewGroup是什么意思
应该去看下源码,parent是item的view的父视图,调整item宽高用的,你自慎桥定义一个viewGroup的时候除了通常要重写onLayout onMeasure等凳孝清方法,计算子view的宽高,如果有了这个parent参数,并且后面的attachToRoot值为否,则会从parent中提取layout_width和layout_height组成LayoutParams,设给convertView。
源码枣前:
ViewGroup.LayoutParams params = null;
if (root != null) {
if (DEBUG) {
System.out.println("Creating params from root: " +
root);
}
// Create layout params that match root, if supplied
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
}
if (root != null && attachToRoot) {
root.addView(temp, params);
}
// Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
result = temp;
}
‘肆’ Activity恢复时如何获取Fragment
Activity 在重建的时候会恢复其包含的 FragmentManager ,FragmentManager 又会恢复其管理的 Fragment ,同理 Fragment 也会恢复其包含的 FragmentManager,层层递进,直到全部恢复。
本文主要讨论Activity重建的时候如何获取Fragment的。即如下情况:
具体通过四种方法来获取复用Fragment。
下面将对这四种情况分芹燃别加以分析说明。
首先来一个总结,不建议使用该方法获取Fragment。理由有如下三点:
getFragments方法获取的是所有已经添加到FragmentManager中的Fragment。但是这个FragmentManager中保存的不只是我们定义的Fragment,还有可能会包含其他用途的Fragment。
Fragment不仅仅是界面的载体,同时它可以用来实现生命周期的监听,因为它的生命周期和Activity是一致的,当我们不好监听Activity的生命周期的时候,就可以使用Fragment来辅助监听。图片加载库Glide和Android Jet Pack中的ViewModel都使用了这种模式。
前段时间就遇到过这样的bug
然后就出现了类型转换异常,FragmentA不能被强制转换成FragmentB。
当时我百思不得其解,为什么会出现这个问题啊,我明明是按照Fragment添加到FragmentManager的顺序去获取Fragment的啊。
直到我将getFragments获取到的Fragment列表打印出来才发现,其中的Fragment顺序和我添加到FragmentManager中的顺序是不一致的。
也就是说因为getFragments中获取到的Fragment包含了你不想要的Fragment,而这些Fragment的初始化时机又是不可预料的,所以就不能通过Fragment列表准确定位你需要的Fragment。
这个情况我没有遇到过,参考文章的作者 怪盗kidou 遇到过,就顺便写上了。
在版本25中Activity是新建的请款下,getFragments返回的是null,然后到了26版本,getFragments返回的就是Collectiions.EmpytList()。。。
这就导致原来基于null判断的程序出现bug。
这个方法是通过Fragment中所在的ViewGroup的Android:id定义的id来查找,适合一个ViewGroup中只存在一个Fragment的情况。
当然,如果一个ViewGroup中有多个Fragment的情况下也是可以使用的,不过这个时候获取的就是嫌扮虚最后添加到ViewGroup中的Fragment了。
该方法就是用来处理findFragmentById不适用的情况的。因为是通过Tag来查找Fragment,所以ViewGroup的id也就没用了。
需要注意的地方:
有一种情况下是不能够使用getFragmentById和缺吵getFragmentByTag,那就是使用ViewPager管理Fragment的情况。
这种方法是可用的,但是太过麻烦,可以使用fm.putFragment和fm.getFragment来处理这种情况。
这两个方法的使用如下:
可能有朋友会感觉这个和getFragmentByTag那么像呢,好像没什么区别。
重点来了,因为在ViewPager中添加和移除Fragment是由ViewPager控制的,所以像是
这种方法就不能被使用了,既然无法在添加fragment的时候设置tag,那我们就不能够通过tag直接从FragmentManager中的Fragment列表中获取了。
那putFragment和getFragment方法是怎么做到这一点的呢?
我们查看下这两个方法的源码:
通过上述源码,我们可以看出,putFragment将待存储的Fragment的Tag和mIndex作为一组数据存储在bundle中,然后在getFragment方法内先从bundle中取出对应Tag的mIndex,最后根据这个mIndex从mActive中取出对应的Fragment。
mActive是真正存储Fragment的对象,但是我们不能够直接使用Tag从中取出,因为ViewPager是使用mIndex来作为key值存储Fragment的。所以我们只能够退而求其次,将Tag和mIndex联系起来,达到间接使用Tag取出Fragment的效果。
下面是对上述源码及步骤的图形化表示:
注意事项:
参考: 你真的会用Fragment吗?Fragment复用的那些事儿
‘伍’ Android编程之如何取得View的当前位置
你好,很高兴为你解答
给要添加的view中设置view.setTag(index); index就是viewGroup的子view的个数,这样通过getTag()就能获取到index了
~如果你认可我的回答,请携陪野及时点乱神击【采纳为满意回答】按钮
~~手机提问的朋友在客户端右上角评价点【满意辩喊】即可。
~你的采纳是我前进的动力
~~O(∩_∩)O,记得好评和采纳,互相帮助,谢谢。
‘陆’ 如何获取Android UI元素
appium android获取元素方式:
1. 1.元素标签(tagname) 通过UI的控件类型ListtextFieldsList=driver.findElements(By.tagName( textfield ));
2. 元素的位置(xpath) 具有一核迹蔽定约束的路径抽州祥象标示, 基于XPath方式改州;
3. 元素的值(name) driver.findElement(By.name( Save )).click();通过元素的文本, 标签, 或者id标示;
4. 元素的IDdriver.findElement(By.id(com.example.android.contactmanager:id/contactNameEditText )).getText();
‘柒’ Android TV开发焦点移动源码分析
点可以理解为选中态,在Android TV上起很重要的作用。一个视图控件只有在获得焦点的状态下,才能响应按键的Click事件。
相对于手机上用手指点击屏幕产生的Click事件, 在TV中通过点击遥控器的方向键来控制焦点的移动。当焦点移动到目标控件上之后,按下遥控器的确定键,才会触发一个Click事件,进而去做下一步的处理
在处理焦点的时候,有一些基础的用法需要知道。
首先,一个控件isFocusable()需要为true才有资格可以获取到焦点。如果想要在触摸模式下获取焦点,需要通过setFocusableInTouchMode(boolean)来设置。也可以直接在xml布局文件中指定:
keyEvent 分发过程:
而当按下遥控器的按键时,会产生一个按键事件,就是KeyEvent,包含“上”,“下”,“左”,“右”,“返回”,“确定”等指令。焦点的处理就在KeyEvent的分发当中完成。
首先,KeyEvent会流转到ViewRootImpl中开始进行处理,具体方法是内部类 ViewPostImeInputStage 中的 processKeyEvent :
接下来先看一下KeyEvent在view框架中的分发:
这里也是可以做焦点控制,最好是在 event.getAction() == KeyEvent.ACTION_DOWN 进行.
因为android 的 ViewRootlmpl 的 processKeyEvent 焦点搜索与请求的地方 进行了判断if (event.getAction() == KeyEvent.ACTION_DOWN)
• 首先ViewGroup会一层一层往上执行父类的dispatchKeyEvent方法,如果返回true那么父类的dispatchKeyEvent方法就会返回true,也就代表父类消费了该焦点事件,那么焦点事件自然就不会往下进行分发。
• 然后ViewGroup会判断mFocused这个view是否为空,如果为空就会return false,焦点继续往下传递;如果不为空,那就会return mFocused的dispatchKeyEvent方法返回的结果。这个mFocused其实是ViewGroup中当前获取焦点的子View
发现执行了onKeyListener中的onKey方法,如果onKey方法返回true,那么dispatchKeyEvent方法也会返回true
如果想要修改ViewGroup焦点事件的分发
• 重写view的dispatchKeyEvent方法
• 给某个子view设置onKeyListener监听
下面再来看一下如果一个页面第一次进入,系统是如何确定焦点是定位在哪个view上的
由于DecorView继承自FrameLayout,这里调用的是ViewGroup的requestFocus
descendantFocusability:
• FOCUS_AFTER_DESCENDANTS:先分发给Child View进行处理,如果所有的Child View都没有处理,则自己再处理
• FOCUS_BEFORE_DESCENDANTS:ViewGroup先对焦点进行处理,如果没有处理则分发给child View进行处理
• FOCUS_BLOCK_DESCENDANTS:ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理
因为 PhoneWindow 给 DecoreView 初始化时设置 了 setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS),所以这里默认是FOCUS_AFTER_DESCENDANTS
到此第一次请求焦点的过程基本告一个段落
焦点移动的时候,默认的情况下,会按照一种算法去找在指定移动方向上最近的邻居。在一些情况下,焦点的移动可能跟开发者的意图不符,这时开发者可以在布局文件中使用下面这些XML属性来指定下一个焦点对象:
在KeyEvent分发中已经知道如果分发过程中event没有被消耗,就会根据方向搜索以及请求焦点View
流程一:查找用户指定的下一个焦点
流程二:获取搜索方向上所有可以获取焦点的view,使用算法查找下一个view
addFocusables() 获取搜索方向上可获得焦点的view
descendantFocusability属性决定了ViewGroup和其子view的聚焦优先级
• FOCUS_BLOCK_DESCENDANTS:viewgroup会覆盖子类控件而直接获得焦点
• FOCUS_BEFORE_DESCENDANTS:viewgroup会覆盖子类控件而直接获得焦点
• FOCUS_AFTER_DESCENDANTS:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
addFocusables 的第一个参数views是由root决定的。在ViewGroup的focusSearch方法中传进来的root是DecorView,也可以主动调用FocusFinder的findNextFocus方法,在指定的ViewGroup中查找焦点。
FocusFinder.findNextFocus 查找焦点
‘捌’ android 如何获取一个界面最顶层的view并处理单击事件的分发机制
android事件分发机制 就是一个触摸事件发生了,从一个窗口传递到一个视图,再传递到另外一个视图,最后被消费的过程,在android中还是比较复杂的传递流程如下:
(1) 事件从Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的View(ViewGroup)开始一直往下(子View)传递。子View可以通过onTouchEvent()对事件进行处理。
(2) 事件由父View(ViewGroup)传递给子View,ViewGroup可以通过onInterceptTouchEvent()对事件做拦截,停止其往下传递。
‘玖’ android基础-viewgroup的测量,布局,绘制
相关文章
android基础-view的测量,布局,绘制
viewgroup的作用主要用于管理子view,而在测量的时候可以分两种情况
关于viewgroup遍历子view去慧胡测量的方法,android中已经帮我们封装了两个常用方法:
protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec)
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)
从方法名和方法里面不难看出这两个方法的区别,就是后者把子view的padding和margin也考虑了进去,不过他们最终调用的都是子view的 view.measure(int wSpec,int hSpec) 方法该方法回触发子view的 onMeasure 方法
最后在测量子view之后,就要对自身大小做决定了,同样是根据不同的测量模式来确定最终的大小,并且最后需要调用
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight)
该方法来设置viewgroup的宽高
viewgroup的测量栗子如下:
在自定义viewgroup的时候,我前埋拦们必须重写如下方法:
该方法主要就是通知子view去设置他们的布局位置,之前 android基础-view的测量,布局,绘制 的篇章也已经详细说明了view.layout方法的过程
viewgroup通知情况下不需要绘制,因为他本身就没有需要绘制的东西,如果不是指定了viewgroup的背景色,那么viewgroup的onDraw方法都不会被调用。但是,viewgroup会使用dispatchDraw()方法来绘制其子view,其过程同样是通过变遍历所有的子view,并调用子view的绘制方法来完成绘制工作
注意对于viewgroup而言onDraw()先于dispatchDraw()执行,用于本身控件的绘制,dispatchDraw()用于子控件的绘制,所以如果想对于viewgroup中绘制完子view之后在对其修改,我们可以在dispatchDraw调用surper方法之前做自己想要的绘制效果,这样避免了被子view的覆盖
viewgroup的测量,布局,绘制,其实都只是用来管理和通知子液镇view去具体实现,可能最主要就是onLayout方法去定义子view的显示位置,其他的核心都是在view中做处理的,所以先理解清楚view的显示过程,那么再来理解viewgroup的显示过程,就会容易理解许多
《Android群英传》¬
‘拾’ Android问题 ,取得View中的控件
你在写Listview的adapter的getview返回的应该是一个包括一张带洞ImageView和一个ProgressBar,的ViewGroup,不管你是用LinearLayout还则隐是其他的layout,总之是个ViewGroup;
你在另个一Activity中,取到ListView里面的View,实际上就是个ViewGroup,可以把这个view强转成ViewGroup对象,再通过getChildAt(0),getChildAt(1),分别取得的子view就是ImageView和蠢盯枯ProgressBar。