如何在解析的XML标记上检查Null值

时间:2013-03-08 18:06:53

标签: android xml android-layout xml-parsing android-listview

目前我正在构建这个Android应用程序,让我难以理解的一件事是句柄ListView所有项目都以我需要的顺序显示但是如果一个标签有一个空白值它会显示为一个单行对象只占用空间并将布局隔开。

Error

此图像ListView项目中的所有空间都是一个正在发送的空字符串,我将其解析。 我想简单地知道处理这个错误的最佳方法吗?

我的ListView项目的XML:

<?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:id="@+id/ContactTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/Name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/ContactTitle"
        android:layout_below="@+id/ContactTitle"
        android:layout_marginRight="17dp"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/MainPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/Name"
        android:layout_below="@+id/Name"
        android:textColor="@color/White"/>

    <TextView
        android:id="@+id/Cell"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/MainPhone"
        android:layout_below="@+id/MainPhone"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/Fax"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/Cell"
        android:layout_below="@+id/Cell"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/Email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/Fax"
        android:layout_below="@+id/Fax"
        android:ellipsize="marquee"
        android:textColor="@color/EmailColor" />

</RelativeLayout>

我需要检查空TextViews并隐藏它们。 我的代码在这里:

protected void onPostExecute(String result) {
            String xml = result;
            String KEY_ITEM = "Contact";
            String KEY_CONTACTTITLE = "ContactTitle";
            String KEY_NAME = "Name";
            String KEY_MAINPHONE = "Phone";
            String KEY_CELLPHONE = "Cell";
            String KEY_FAX = "Fax";
            String KEY_EMAIL = "Email";
            ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

            Document doc = getDomElement(xml);
            if (xml != null) {
                {
                    NodeList nl = doc.getElementsByTagName(KEY_ITEM);
                    for (int i = 0; i < nl.getLength(); i++) {
                        HashMap<String, String> map = new HashMap<String, String>();
                        Element e = (Element) nl.item(i);
                        if (getValue(e, KEY_CONTACTTITLE) != null) {
                            map.put(KEY_CONTACTTITLE,
                                    getValue(e, KEY_CONTACTTITLE));
                        } else {
                            TextView contactTitle = (TextView) findViewById(R.id.ContactTitle);
                        }
                        if (getValue(e, KEY_NAME) != null) {
                            map.put(KEY_NAME, getValue(e, KEY_NAME));
                        }
                        if (getValue(e, KEY_MAINPHONE) != null) {
                            map.put(KEY_MAINPHONE, getValue(e, KEY_MAINPHONE));
                        }

                        if (getValue(e, KEY_CELLPHONE) != null) {
                            map.put(KEY_CELLPHONE, getValue(e, KEY_CELLPHONE));
                        }

                        if (getValue(e, KEY_FAX) != null) {
                            map.put(KEY_FAX, getValue(e, KEY_FAX));
                        }

                        if (getValue(e, KEY_EMAIL) != null) {
                            map.put(KEY_EMAIL, getValue(e, KEY_EMAIL));
                        }

                        menuItems.add(map);
                        menuItems = simple;
                    }

                    String[] hashMapObjects = { KEY_CONTACTTITLE, KEY_NAME,
                            KEY_MAINPHONE, KEY_CELLPHONE, KEY_FAX, KEY_EMAIL };
                    int[] listItemObjects = { R.id.ContactTitle, R.id.Name,
                            R.id.MainPhone, R.id.Cell, R.id.Fax, R.id.Email };

                      ListAdapter adapter = new SimpleAdapter(
                      MoveContactsActivity.this, menuItems,
                      R.layout.listed_contacts, hashMapObjects,
                      listItemObjects);
                     setListAdapter(adapter);

我正在尝试检查值是否为null以将对象添加到HashMap。这当然不起作用,我想知道如何检查null TextViews并隐藏它们。

6 个答案:

答案 0 :(得分:2)

如果View.setVisibility(View.GONE)中没有任何内容可显示,您只需致电TextView即可。由于您使用的是SimpleAdapter并且没有自定义getView方法,因此最简单的方法是使用SimpleAdapter.ViewBinder

String[] hashMapObjects = { 
        KEY_CONTACTTITLE, KEY_NAME, KEY_MAINPHONE, KEY_CELLPHONE, KEY_FAX, KEY_EMAIL 
};

int[] listItemObjects = { 
        R.id.ContactTitle, R.id.Name, R.id.MainPhone, R.id.Cell, R.id.Fax, R.id.Email 
};

SimpleAdapter adapter = new SimpleAdapter(MoveContactsActivity.this, menuItems, R.layout.listed_contacts, hashMapObjects, listItemObjects);
SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {
    @Override
    public boolean setViewValue(View view, Object object, String value) {
        if (!(view instanceof TextView)) {
            return false;
        }

        final TextView text = (TextView) view;

        text.setVisibility(TextUtils.isEmpty(value) ? View.GONE : View.VISIBLE);
        text.setText(value);

        return true;
    }
};

adapter.setViewBinder(binder);
setListAdapter(adapter);

答案 1 :(得分:1)

我不知道您的列表视图项结构。

我的建议是:

检查标记是否为null并执行某些操作来解决此问题,例如设置TextView visibility = GONE。

答案 2 :(得分:1)

正如威廉所说,如果文本为空或为空,您可以扩展简单适配器以向视图添加可见性:

public class MyAdapter extends SimpleAdapter {

    public MyAdapter(Context context, List<? extends Map<String, ?>> data,
            int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
            if(convertView!=null) //reset the visibility if a convert view is used
                convertView.setVisibility(View.VISIBLE);

        View v = super.getView(position, convertView, parent);

        //text recovering from data source. here I check the name field
        //you can add any test and hide any views using views id and setVisibility method
        String displayedText = ((HashMap<String, String>) this.getItem(position)).get("Name"); 
        if( displayedText == null || displayedText.isEmpty())
            v.setVisibility(View.GONE);


        return v;
    }
}

使用此类而不是SimpleAdapter,然后您可以使用getView方法对ListView的任何视图的任何字段添加条件。

获取信息:getView返回将在ListView中的给定位置显示的视图,您可以通过恢复给定位置的项目来根据数据源更改这些视图中的任何内容。

答案 3 :(得分:1)

请避免将空值添加到集合中,该集合将传递给适配器以填充列表视图

boolean elementFound = false;
for (int i = 0; i < nl.getLength(); i++) {
    HashMap<String, String> map = new HashMap<String, String>();
    Element e = (Element) nl.item(i);
    elementFound = false;
    if (getValue(e, KEY_CONTACTTITLE) != null) {
        map.put(KEY_CONTACTTITLE,
                getValue(e, KEY_CONTACTTITLE));
        elementFound = true;
    } else {
        TextView contactTitle = (TextView) findViewById(R.id.ContactTitle);
    }
    if (getValue(e, KEY_NAME) != null) {
        map.put(KEY_NAME, getValue(e, KEY_NAME));
        elementFound = true;
    }
    if (getValue(e, KEY_MAINPHONE) != null) {
        map.put(KEY_MAINPHONE, getValue(e, KEY_MAINPHONE));
        elementFound = true;
    }

    if (getValue(e, KEY_CELLPHONE) != null) {
        map.put(KEY_CELLPHONE, getValue(e, KEY_CELLPHONE));
        elementFound = true;
    }

    if (getValue(e, KEY_FAX) != null) {
        map.put(KEY_FAX, getValue(e, KEY_FAX));
        elementFound = true;
    }

    if (getValue(e, KEY_EMAIL) != null) {
        map.put(KEY_EMAIL, getValue(e, KEY_EMAIL));
        elementFound = true;
    }
    if(elementFound){
        menuItems.add(map);
    }
    //I don't understand whay are you doing this
    //menuItems = simple;
}

答案 4 :(得分:1)

使用非空String检查您的值,例如:

if (getValue(e, KEY_NAME) != null && !getValue(e,KEY_NAME).toString().equalsIgnoreCase("")) {
 map.put(KEY_NAME, getValue(e, KEY_NAME));
}

答案 5 :(得分:1)

您正在使用SimpleAdapter。这很好,但我认为变更管理是软件的关键。您应该扩展BaseAdapter并应该处理getView方法。

我知道SimpleAdapter实施起来非常快,但是当变化来临时,它会骚扰你。如果您现在为custom adapter再写一个文件,那么在更改时您将会放松。

ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;
    if (convertView == null) {

        convertView = infalter.inflate(R.layout.list_row, null);
        holder = new ViewHolder();
        holder.tvRawName = (TextView) convertView
                .findViewById(R.id.tvRawName );
        holder.tvRawEmail= (TextView) convertView
                .findViewById(R.id.tvRawEmail);
        convertView.setTag(holder);

    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    try {
         if(data.get(position).get("Email")!=null && data.get(position).get("Email").length()>0)
         {
                holder.tvRawEmail.setVisibility(View.VISIBLE);
                holder.tvRawEmail.setText(data.get(position).get("Email"));
         }else
         {
                holder.tvRawEmail.setVisibility(View.GONE);
         }

    } catch (Exception e) {
        e.printStackTrace();
    }

//do like for all

    return convertView;
}

public class ViewHolder {
    TextView tvRawName;
    TextView tvRawEmail;
}
相关问题