Android-任何活动的rootview层次结构中存在的所有视图的相对路径生成器
背景 在android布局文件中,有一个或多个UI元素和视图组。有时我们不需要为视图提供Android-任何活动的rootview层次结构中存在的所有视图的相对路径生成器,android,android-layout,Android,Android Layout,背景 在android布局文件中,有一个或多个UI元素和视图组。有时我们不需要为视图提供id值(唯一标识符)。在这种情况下,我们无法通过说findViewByid()来找到视图。因此,我们不能操纵它们 问题是 我们如何为任何活动的所有视图生成路径,示例如下: content>LinearLayout-0>RelativeLayout-3>LinearLayout-0>TextView-2 上面这行的意思是 内容是主要布局 线性布局是最顶层的布局 RelativeLayout-3是最顶层布局的第三
id
值(唯一标识符)。在这种情况下,我们无法通过说findViewByid()
来找到视图。因此,我们不能操纵它们
问题是
我们如何为任何活动的所有视图生成路径,示例如下:
content>LinearLayout-0>RelativeLayout-3>LinearLayout-0>TextView-2
上面这行的意思是
String path = getViewPath(view);
及
用例:
实际上,服务器会通过添加视图路径向移动应用程序广播一些命令
然后移动应用程序将从路径中找到视图并更改视图的属性我认为最简单的解决方案是使用
视图组和方法
因此,您可以将每个所需的视图
转换为视图组
,并可以调用上述方法。但是,这不会返回字符串
路径。但是您仍然可以获得一个相对的层次结构,并按照您的特定用例进行工作 在上述问题的解决方案下面,我创建了获取视图路径的方法和按路径获取视图的方法
干杯
package com.test;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.Window;
import java.util.Arrays;
public class CustomViewIdManager {
private static final String ACTIVITY_CLASS_SEPARATOR = "@";
private static final String VIEW_SEPARATOR = ">";
private static final String VIEW_POSITION_SEPARATOR = ":";
private static final String MAIN_CONTENT_LAYOUT_NAME = "content";
/**
* Find given view path in activity hierarchy
*
* @param view
* @param activity
* @return Path given view
*/
public static String generateViewPathInActivityViewHierarchy(View view, Activity activity) {
String path = "";
View currentView = view;
ViewParent currentParent;
do {
currentParent = currentView.getParent();
if (currentView.getId() == Window.ID_ANDROID_CONTENT) {
path = activity.getLocalClassName() + ACTIVITY_CLASS_SEPARATOR + MAIN_CONTENT_LAYOUT_NAME + path;
break;
} else {
path = VIEW_SEPARATOR + currentView.getClass().getSimpleName() + VIEW_POSITION_SEPARATOR + getSelfIndexInParent((View) currentParent, currentView) + path;
}
currentView = (View) currentView.getParent();
} while (true);
return path;
}
/**
* Finding the view by given path in activity view hierarchy
* @param path
* @param activity
* @return
*/
public static View findViewByCustomPath(String path, Activity activity) {
String[] activitySplitting = path.split(ACTIVITY_CLASS_SEPARATOR);
String[] viewSplitting = activitySplitting[1].split(VIEW_SEPARATOR);
View viewLooker = null;
if (viewSplitting[0].equalsIgnoreCase(MAIN_CONTENT_LAYOUT_NAME)) {
viewLooker = ViewUtil.getContentView(activity);
}
return viewFinder(viewLooker, Arrays.copyOfRange(viewSplitting, 1, viewSplitting.length));
}
public static View viewFinder(View view, String[] restPath) {
View viewToSendBack;
String singleView = restPath[0];
String[] viewPositioningSplitting = singleView.split(VIEW_POSITION_SEPARATOR);
viewToSendBack = ((ViewGroup) view).getChildAt(Integer.parseInt(viewPositioningSplitting[1]));
if (restPath.length > 1) {
return viewFinder(viewToSendBack, Arrays.copyOfRange(restPath, 1, restPath.length));
} else {
return viewToSendBack;
}
}
/**
* This will calculate the self position inside view
*
* @param parent
* @param view
* @return index of child
*/
public static int getSelfIndexInParent(View parent, View view) {
int index = -1;
if (parent instanceof ViewGroup) {
ViewGroup viewParent = (ViewGroup) parent;
for (int i = 0; i < viewParent.getChildCount(); ++i) {
View child = viewParent.getChildAt(i);
++index;
if (child == view) {
return index;
}
}
}
return index;
}
}
package.com.test;
导入android.app.Activity;
导入android.util.Log;
导入android.view.view;
导入android.view.ViewGroup;
导入android.view.ViewParent;
导入android.view.Window;
导入java.util.array;
公共类CustomViewIdManager{
私有静态最终字符串活动\u类\u分隔符=“@”;
私有静态最终字符串视图_SEPARATOR=“>”;
私有静态最终字符串视图_位置_分隔符=“:”;
私有静态最终字符串MAIN\u CONTENT\u LAYOUT\u NAME=“CONTENT”;
/**
*在活动层次结构中查找给定的视图路径
*
*@param视图
*@param活动
*@返回路径给定视图
*/
公共静态字符串GenerateViewPathinaActivityViewWhierArchy(视图、活动){
字符串路径=”;
视图当前视图=视图;
ViewParent-currentParent;
做{
currentParent=currentView.getParent();
if(currentView.getId()==Window.ID\u ANDROID\u内容){
path=activity.getLocalClassName()+活动\类\分隔符+主\内容\布局\名称+路径;
打破
}否则{
路径=视图\分隔符+currentView.getClass().getSimpleName()+视图\位置\分隔符+getSelfIndexInParent((视图)currentParent,currentView)+路径;
}
currentView=(视图)currentView.getParent();
}虽然(正确);
返回路径;
}
/**
*通过活动视图层次结构中的给定路径查找视图
*@param路径
*@param活动
*@返回
*/
公共静态视图findViewByCustomPath(字符串路径、活动){
String[]ActivitySpliting=path.split(活动\类\分隔符);
字符串[]ViewSpliting=ActivitySpliting[1]。拆分(视图分隔符);
查看查看者=空;
if(视图拆分[0]。相等信号案例(主内容\布局\名称)){
viewLooker=ViewUtil.getContentView(活动);
}
返回取景器(取景器,数组。copyOfRange(取景器分割,1,取景器分割。长度));
}
公共静态取景器(视图,字符串[]restPath){
查看视图返回;
字符串singleView=restPath[0];
String[]viewPositionSpliting=singleView.split(视图位置分隔符);
viewToSendBack=((ViewGroup)视图).getChildAt(Integer.parseInt(ViewPositionsSpliting[1]);
如果(restPath.length>1){
返回取景器(viewToSendBack,Arrays.copyOfRange(restPath,1,restPath.length));
}否则{
返回viewToSendBack;
}
}
/**
*这将计算内部视图中的自身位置
*
*@param父级
*@param视图
*@child返回索引
*/
公共静态int getSelfIndexInParent(视图父对象,视图视图){
int指数=-1;
if(视图组的父实例){
ViewGroup viewParent=(ViewGroup)父对象;
对于(int i=0;i
没有必要重新发明轮子。如果您需要对视图的引用,除了创建视图路径之外,还有很多方法可以获得。如果希望从视图中引用,请执行以下操作:
从Xml:
如果您的视图是使用XML
创建的,那么引用这些View
的最佳方法是设置一个id,如:
android:id="@+id/my_id"
当您想在我们使用的代码中引用该视图时:
(AnyParentOfTheView).findViewById(R.id.my_id);
来自代码(动态):
如果您的视图是动态创建的,那么我们不能使用方法(Parent).findViewById(int-id)
或者
当您动态创建视图时,我们可以使用我们称之为标记的内容来引用它们。与ID不同,标记是在代码中动态设置到视图的。标记可以是任何Java对象
,但我们通常使用字符串,但您可以将标记与任何对象
关联,然后使用方法findViewWithTag(对象标记)
例如:
.......
TextView myTextView=new TextView(this);
myTextView.setTag("txt");
.......
当我们想在代码中引用我们的TextView
时,我们调用如下方法:
TextView myTextView=(TextView)findViewWithTag("txt");
这样,我们就可以引用我们的视图
,因此如果您想要文本视图
,您可以这样做。View
类甚至支持在代码中获取视图标记的方法,如:
String myTag=myTextView.getTag();
针对您的用例的最佳方法是:
setTag(Object obj)
setTag (int key, Object tag)
getTag(int key)
getTag()
findViewWithTag()
给ge
setTag(Object obj)
setTag (int key, Object tag)
getTag(int key)
getTag()
findViewWithTag()