我正在尝试创建一个功能,将当前分散在项目不同部分的信息整合在一起。
作为此任务的一部分,我有一个布局文件,其中包含以下内容...基本上是一组行,每行都有一个标签(TextView
)和一个UI元素(例如{{ 1}},CheckBox
或Spinner
)来收集用户的信息:
EditText
我已经拥有了UI元素的所有<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/MyLinearLayout.Section"
android:id="@+id/section_pressure" >
<TableLayout style="@style/MyTableLayout"
android:id="@+id/table_pressure" >
<TableRow style="@style/MyTableRow" >
<TextView
style="@style/MyTextView.Label.WithHelp"
android:tag="label_show"
android:text="@string/label_show" />
<CheckBox
style="@style/MyCheckBox"
android:id="@+id/pressure" />
</TableRow>
<TableRow style="@style/MyTableRow" >
<TextView
style="@style/MyTextView.Label.WithHelp"
android:tag="label_unit"
android:text="@string/label_unit" />
<Spinner
style="@style/MySpinnerStyle"
android:id="@+id/pressureUnit" />
</TableRow>
</TableLayout>
</LinearLayout>
值的数组,并且我想要生成相应android:id
标签的另一个数组。
e.g。来自android:text
我希望从R.id.pressureUnit
找到关联的R.string.label_unit
,以便我有一个关于每个UI元素使用什么标签的中央记录...目前该信息分散在许多不同的布局文件。
这可以通过编程方式实现吗?
答案 0 :(得分:3)
根据我的理解,您希望找到给定视图的兄弟视图的@string
资源ID。
假设您的xml
文件已经膨胀,您可以执行以下操作:
private int getSiblingStringId(@IdRes int viewId) {
View uiElement = findViewById(viewId);
ViewGroup parent = (ViewGroup) uiElement.getParent();
// iterate through the siblings
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
if (view instanceof TextView) {
String value = ((TextView) view).getText().toString();
// found
return getStringIdFromValue(value);
}
}
throw new IllegalArgumentException("no TextView sibling for " + viewId);
}
private int getStringIdFromValue(String value) {
// get all fields using reflection
Field[] fields = R.string.class.getDeclaredFields();
for (Field field : fields) {
int stringResId = getResources().getIdentifier(field.getName(), "string", getPackageName());
String s = getString(stringResId);
if (s.equals(value)) return stringResId;
}
throw new IllegalArgumentException("no matching string for " + value);
}
以上代码适用于活动。您可能需要为其他类稍微修改一下。 (您需要致电findViewById
,getResources
和getString
)
答案 1 :(得分:0)
好吧,我会为每个表格行设置一个ID。然后,通过迭代行的子项,以编程方式获取每行下的每个子视图。从那里,您可以通过使用instanceof简单地确定您所在的位置来轻松操纵每个视图。但是,让我们假设你不能改变它,你仍然可以这样做,但它可能效率不高。
由于我不知道你的id数组的结构,我只假设它是一个名为uiIds的整数数组。然后,你必须做类似
的事情TableLayout layout = findViewById(R.id.table_pressure);
TableRow tr = null;
View rowChild = null;
TextView tv = null;
View secondaryView = null;
int tableChildCount = layout.getChildCount();
int rowChildCount = 0;
// Since I don't really know the structure of your array of ids,
// I just assume its an array of integers called uiIds
//This will contain the corresponding text strings of every textview
List<String> textLabels = Arrays.asList(new String[uiIds.length]);
// Go over all the rows on your table
for (int i = 0; i < tableChildCount; i++) {
// I'm assuming that you only have rows as the children of your table
tr = (TableRow) layout.getChildAt(i); //This is the row
rowChildCount = tr.getChildCount();
tv = null;
secondaryView = null;
// Now go over all the children of the current row i
for (int j = 0; j < rowChildCount; j++) {
// Here I'm also assuming you only have two children on every row
rowChild = getChildAt(j);
// At this point, the view v could be any type of the ones you have
// used. Since we are interested in TextView simply do an instanceof
if ( rowChild instanceof TextView ) {
tv = (TextView) v;
} else {
// This is the other view in the row. The ones from which you alreade have its ids
// e.g. the spinner with id pressureUnit
secondaryView = rowChild; //We do not need to cast
}
}
// Now we construct the array
if (tv != null && secondaryView != null) {
// The id we just obtained is one from the ones you have already saved
// in an array called uiIds
int secondaryViewId = secondaryView.getId();
//Now, we need to find the index of this id in uiIds
for (int idx = 0; idx < uiIds.length; idx++) {
if ( uiIds[idx] == secondaryViewId ) {
//We have found a match. Then just add the text of the textview in the corresponding index of our new array
textLabels.set(idx,tv.getText().toString());
}
}
}
}
// At this point, textLabels should contain the text of the text view on every row
// such that the ith element in the array you already have corresponds to
// ith element of the array we just created.
// In other words, if uiIds[0] is equals to R.id.pressureUnit, then,
// textLabels.get(0) is equals to R.string.label_unit
我直接在文本编辑器上编辑了答案,因此它可能有一些sintax错误。希望这能解决您的问题,或至少给您一个想法。
答案 2 :(得分:0)
为了概述标签映射,我建议更系统地编码,在这种情况下,将标签命名为id。
> snappy@6.0.4 install /usr/src/app/node_modules/snappy
> node-gyp rebuild
make: Entering directory '/usr/src/app/node_modules/snappy/build'
CXX(target) Release/obj.target/snappy/deps/snappy/snappy-1.1.7/snappy-sinksource.o
CXX(target) Release/obj.target/snappy/deps/snappy/snappy-1.1.7/snappy-stubs-internal.o
CXX(target) Release/obj.target/snappy/deps/snappy/snappy-1.1.7/snappy.o
AR(target) Release/obj.target/deps/snappy/snappy.a
COPY Release/snappy.a
CXX(target) Release/obj.target/binding/src/binding.o
In file included from ../src/./binding.h:3:0,
from ../src/binding.cc:1:
/root/.node-gyp/10.2.0/include/node/node.h:53:50: fatal error: core.h:
No such file or directory
#include "core.h" // NOLINT(build/include_order)
^
compilation terminated.
make: Leaving directory '/usr/src/app/node_modules/snappy/build'
make: *** [binding.target.mk:102:
Release/obj.target/binding/src/binding.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit
(/usr/local/lib/node_modules/npm/node_modules/node-
gyp/lib/build.js:258:23)
gyp ERR! stack at ChildProcess.emit (events.js:182:13)
gyp ERR! stack at Process.ChildProcess._handle.onexit
(internal/child_process.js:237:12)
gyp ERR! System Linux 4.9.87-linuxkit-aufs
gyp ERR! command "/usr/local/bin/node"
"/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js"
"rebuild"
gyp ERR! cwd /usr/src/app/node_modules/snappy
gyp ERR! node -v v10.2.0
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok
=&gt; @+id/pressure
@string/label_pressure
=&gt; @+id/pressureUnit
我知道这不是你问题的直接答案。但是我认为,如果你以这种方式工作,你根本不需要映射的中央表格,你的布局变得更具可读性。 Android Studio可以让您轻松进行此类更改。