简体   繁体   English

Android如何用两个不同的项目给ListView充气

[英]Android how to inflate ListView with two different items

I am trying to inflate listView with two different layouts using ArrayAdapter. 我正在尝试使用ArrayAdapter为两个不同的布局填充listView。

I want to show some user posts. 我想显示一些用户帖子。 If it contains a picture use one layout if it does not use second. 如果包含图片,则不使用第二种布局。

I am doing so far 我到目前为止

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Post post = getItem(position);

    boolean noImg = post.mImgUrl1 == null && post.mImgUrl2 == null;

    if (convertView == null){

        if (noImg)
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item_no_img, parent ,false);
        else
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item, parent, false);
    }

    if (noImg == false) {
        mTitle = (TextView) convertView.findViewById(R.id.tv_titlePost);
        mText = (TextView) convertView.findViewById(R.id.tv_textPost);
        mImage = (ImageView) convertView.findViewById(R.id.iv_postimg);
    }

    else {
        mNoImgTitle = (TextView) convertView.findViewById(R.id.tv_noImgTitle);
        mNoImgText = (TextView) convertView.findViewById(R.id.tv_noImgText);
    }

    if (noImg) {
        mNoImgTitle.setText(post.mTitle);
        mNoImgText.setText(post.mText);

        if (post.mImgUrl1 != null)
            Glide.with(mImage.getContext()).load(post.mImgUrl1).into(mImage);

        else  Glide.with(mImage.getContext()).load(post.mImgUrl2).into(mImage);
    }
    else {
        mNoImgTitle.setText(post.mTitle);
        mNoImgText.setText(post.mText);
    }

    return convertView;
}

But i realized that textviews from second layout cannot be found by findViewById function. 但是我意识到findViewById函数无法找到第二种布局的textviews。 And it always returns a null-pointer. 并且它总是返回一个空指针。

What are my solutions ? 我有什么解决方案? Should i make only one Layout and somehow trick it using visibility ? 我应该只制作一个布局,还是以可见性以某种方式欺骗它吗? Or there is a way ? 还是有办法?

With BaseAdapter you can create more complex layouts. 使用BaseAdapter可以创建更复杂的布局。 Try using it. 尝试使用它。

Here is the example of use for your situation: 这是根据您的情况使用的示例:

Activity: 活动:

public class TestActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    String[] data={"false","false","true","true","false","true"};
    ListView listViewTest=(ListView)findViewById(R.id.listViewTest);
    TestAdapter testAdapter=new TestAdapter(data);
    listViewTest.setAdapter(testAdapter);
}
}

Adapter: 适配器:

public class TestAdapter extends BaseAdapter {
private String[] data;


TestAdapter(String data[]) {
    this.data = data;
}

@Override
public int getCount() {
    return data.length;
}

@Override
public Object getItem(int i) {
    return data[i];
}

@Override
public long getItemId(int i) {
    return i;
}


public View getView(int position, View convertView, ViewGroup parent) {
    if (data[position].equals("false")) {
        convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_no_img, parent, false);
    } else if (data[position].equals("true")) {
        convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_img, parent, false);
    }
    return convertView;
}
}

Layouts: 布局:

activity_main activity_main

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
    android:id="@+id/listViewTest"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</ListView>

list_item_no_img list_item_no_img

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/textViewTest"
    android:gravity="center"
    android:layout_centerInParent="true"
    android:textSize="32sp"
    android:text="Test"/>
</RelativeLayout>

list_item_img list_item_img

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/textViewTest"
    android:gravity="center"
    android:layout_centerInParent="true"
    android:textSize="32sp"
    android:text="Test"/>
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/ic_launcher"
    android:layout_marginStart="5dp"
    android:layout_marginLeft="5dp"
    android:layout_centerVertical="true"
    android:layout_toRightOf="@+id/textViewTest"
    android:layout_toEndOf="@+id/textViewTest" />
</RelativeLayout>

Result: 结果:

There are a few different scenarios that you will see when getView() is called: 调用getView()时,会看到几种不同的情况:

  1. convertView is null: In this case just create the layout that you need depending upon noImg ; convertView为null:在这种情况下,只需根据noImg创建所需的布局noImg

  2. convertView is defined but is of the wrong type. convertView已定义,但类型错误。 In this case, you will need to discard the old view and create the one you need; 在这种情况下,您将需要丢弃旧视图并创建所需的视图。

  3. convertView is defined but is of the correct type, in which case, we do nothing with it. convertView已定义但类型正确,在这种情况下,我们不对其进行任何处理。

The following code is one approach to making sure that you are always working with the right layout and can find the ids that you expect. 以下代码是一种确保您始终使用正确的布局并可以找到所需ID的方法。 This code uses a tag in the inflated layout to identify the layout type that can be checked. 此代码在膨胀的布局中使用标签来标识可以检查的布局类型。

if (convertView == null || noImg != (boolean) convertView.getTag()) {
    // Either there is no view defined or it is the wrong type. Create
    // the type we need.
    if (noImg) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item_no_img, parent, false);
    } else {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item, parent, false);
    }
    convertView.setTag(noImg);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM