簡體   English   中英

Android - 讓孩子進入一個視圖?

[英]Android - get children inside a View?

給定一個視圖,我如何才能在其中獲取子視圖?

所以我有一個自定義視圖,調試器顯示在mChildren下還有 7 個其他視圖。 我需要一種訪問這些視圖的方法,但似乎沒有公共 API 來執行此操作。

有什么建議?

編輯:

我的自定義視圖繼承自AdapterView

for(int index = 0; index < ((ViewGroup) viewGroup).getChildCount(); index++) {
    View nextChild = ((ViewGroup) viewGroup).getChildAt(index);
}

那行嗎?

如果你不僅想得到所有直接的孩子,還想得到所有孩子的孩子等等,你必須遞歸地做:

private ArrayList<View> getAllChildren(View v) {

    if (!(v instanceof ViewGroup)) {
        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        return viewArrayList;
    }

    ArrayList<View> result = new ArrayList<View>();

    ViewGroup vg = (ViewGroup) v;
    for (int i = 0; i < vg.getChildCount(); i++) {

        View child = vg.getChildAt(i);

        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        viewArrayList.addAll(getAllChildren(child));

        result.addAll(viewArrayList);
    }
    return result;
}

要使用結果,您可以執行以下操作:

    // check if a child is set to a specific String
    View myTopView;
    String toSearchFor = "Search me";
    boolean found = false;
    ArrayList<View> allViewsWithinMyTopView = getAllChildren(myTopView);
    for (View child : allViewsWithinMyTopView) {
        if (child instanceof TextView) {
            TextView childTextView = (TextView) child;
            if (TextUtils.equals(childTextView.getText().toString(), toSearchFor)) {
                found = true;
            }
        }
    }
    if (!found) {
        fail("Text '" + toSearchFor + "' not found within TopView");
    }

您始終可以通過 View.findViewById() http://developer.android.com/reference/android/view/View.html#findViewById(int ) 訪問子視圖。

例如,在活動/視圖中:

...
private void init() {
  View child1 = findViewById(R.id.child1);
}
...

或者如果您有對視圖的引用:

...
private void init(View root) {
  View child2 = root.findViewById(R.id.child2);
}

我將提供此答案作為替代@IHeartAndroid 的遞歸算法,用於發現視圖層次結構中的所有子View 請注意,在撰寫本文時,遞歸解決方案存在缺陷,因為它將在其結果中包含重復項。

對於那些難以理解遞歸的人來說,這里有一個非遞歸的替代方案。 意識到這也是遞歸解決方案的深度優先方法的廣度優先搜索替代方案,您將獲得獎勵積分。

private List<View> getAllChildrenBFS(View v) {
    List<View> visited = new ArrayList<View>();
    List<View> unvisited = new ArrayList<View>();
    unvisited.add(v);

    while (!unvisited.isEmpty()) {
        View child = unvisited.remove(0);
        visited.add(child);
        if (!(child instanceof ViewGroup)) continue;
        ViewGroup group = (ViewGroup) child;
        final int childCount = group.getChildCount();
        for (int i=0; i<childCount; i++) unvisited.add(group.getChildAt(i));
    }

    return visited;
}

幾個快速測試(不是正式的)表明這個替代方案也更快,盡管這很可能與另一個答案創建的新ArrayList實例的數量有關。 此外,結果可能因視圖層次結構的垂直/水平而異。

交叉發布自: Android | 獲取 ViewGroup 的所有子元素

這是一個建議:您可以獲得由R使用其給定名稱(例如My Str )生成的ID (例如由android:id="@+id/..My Str..指定)。使用的代碼片段getIdentifier()方法將是:

public int getIdAssignedByR(Context pContext, String pIdString)
{
    // Get the Context's Resources and Package Name
    Resources resources = pContext.getResources();
    String packageName  = pContext.getPackageName();

    // Determine the result and return it
    int result = resources.getIdentifier(pIdString, "id", packageName);
    return result;
}

Activity ,與findViewById結合使用的示例是:

// Get the View (e.g. a TextView) which has the Layout ID of "UserInput"
int rID = getIdAssignedByR(this, "UserInput")
TextView userTextView = (TextView) findViewById(rID);

作為對 2018 年之后遇到此問題的人的更新,如果您使用的是 Kotlin,則可以簡單地使用Android KTX擴展屬性ViewGroup.children來獲取 View 的直接子項的序列。

此方法采用布局內的所有視圖,這類似於 Alexander Kulyakhtin 的回答。 不同之處在於,它接受任何類型的父布局並返回一個視圖數組列表。

public List<View> getAllViews(ViewGroup layout){
        List<View> views = new ArrayList<>();
        for(int i =0; i< layout.getChildCount(); i++){
            views.add(layout.getChildAt(i));
        }
        return views;
}

為了刷新表格布局(TableLayout),我最終不得不使用上面提到的遞歸方法來獲取所有孩子的孩子等等。

我的情況有些簡化,因為我只需要使用 LinearLayout 和從它擴展而來的那些類,例如 TableLayout。 我只對尋找 TextView 孩子感興趣。 但我認為它仍然適用於這個問題。

最后一個類作為一個單獨的線程運行,這意味着它可以在為孩子解析之前在后台做其他事情。 代碼小巧簡單,可在github上找到: https : //github.com/jkincali/Android-LinearLayout-Parser

我最近遇到了同樣的問題,並使用Kotlin的擴展功能解決了該問題,如下所示:

fun ViewGroup.getAllChildren(): List<View> {
    val children = ArrayList<View>()
    for (i in 0 until this.childCount) {
        children.add(this.getChildAt(i))
    }
    return children
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM