根据父类型生成LayoutParams

key*_*rdr 13 android android-layout viewgroup

我发现自己需要完全用Java创建一个View而不知道父类的具体类型.

例:

public View getView(int position, View convertView, ViewGroup parent){
    if(null == convertView){
        convertView = new TextView(parent.getContext());
    }
    ((TextView) convertView).setText(getItem(position).getName());
}
Run Code Online (Sandbox Code Playgroud)

现在假设我想改变它,以便convertView在两个方向都是wrap_content.由于这是一个适配器,我想避免将Adapter与父类的具体类型耦合,但我在setLayoutParams()中给出的LayoutParams必须是正确的具体类型,否则应用程序将崩溃(即如果父类是一个ListView它必须是ListView.LayoutParams,如果它是一个LinearLayout,它必须是一个LinearLayout.LayoutParams等).我不想使用switch语句,因为这只是一种更灵活的耦合形式,如果我将这个适配器连接到一个视图,我没想到我仍然会崩溃.有没有通用的方法来做到这一点?

Mic*_*ael 8

您可以使用以下代码执行此操作:

LayoutParams params = parent.generateLayoutParams(null);
Run Code Online (Sandbox Code Playgroud)

编辑:上面的方法不起作用,因为ViewGroup.generateLayoutParams()需要android:layout_widthandroid:layout_height在传递中设置AttributeSet.

如果您使用ViewGroup.LayoutParams任何布局,那么一切都会正常工作.但是如果你使用LinearLayout.LayoutParamsRelativeLayout例如,那么将引发异常.

编辑:有一个解决这个问题的工作方案,我不太喜欢.解决方案是generateLayoutParams()使用有效的呼叫AttributeSet.您可以AttributeSet使用至少两种不同的方法创建对象.其中一个我已实施:

res\layout\params.xml:

<?xml version="1.0" encoding="utf-8"?>

<view xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dip" />
Run Code Online (Sandbox Code Playgroud)

SomeActivity.java:

private void addView(ViewGroup viewGroup, View view) {
    viewGroup.addView(view);
    view.setLayoutParams(generateLayoutParams(viewGroup));
}

private ViewGroup.LayoutParams generateLayoutParams(ViewGroup viewGroup) {
    XmlResourceParser parser = getResources().getLayout(R.layout.params);
    try {
        while(parser.nextToken() != XmlPullParser.START_TAG) {
            // Skip everything until the view tag.
        }
        return viewGroup.generateLayoutParams(parser);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

创建AttributeSet对象的另一种方法是实现AttributeSet接口并使其返回android:layout_width,android:layout_height以及您需要的其他布局属性.