Java 我的自定义适配器一直进入if语句,而不是else语句,从而导致强制转换错误,即使该语句应求值为false

Java 我的自定义适配器一直进入if语句,而不是else语句,从而导致强制转换错误,即使该语句应求值为false,java,android,Java,Android,我有一个自定义阵列适配器,它应该在列表视图中显示两种类型的布局。我在自定义arrayAdapter中使用一个名为isMessage的布尔值来区分它们。即使isMessage在传递对象MessageListDetails之前等于true,因为我在添加对象之前调用prepareForIncomingMessage public class TimedEventsAdapter extends ArrayAdapter<Object> { private List<O

我有一个自定义阵列适配器,它应该在列表视图中显示两种类型的布局。我在自定义arrayAdapter中使用一个名为isMessage的布尔值来区分它们。即使isMessage在传递对象MessageListDetails之前等于true,因为我在添加对象之前调用prepareForIncomingMessage

   public class TimedEventsAdapter extends ArrayAdapter<Object> {

    private List<Object> items;
    private boolean isMessage;
   //  * @param context
   //  * @param textViewResourceId
   //  * @param objects 
    public TimedEventsAdapter(Context context, int textViewResourceId,
            List<Object> objects) {
        super(context, textViewResourceId,objects);
        items = objects;
        isMessage = false;
    }
    public void prepareForIncomingMessage() {
        isMessage = true;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            if(isMessage == false)
            v = vi.inflate(R.layout.complete_event_discription, null);
           else
            v = vi.inflate(R.layout.message_list_view, null);
        }
       if(isMessage == false){ // problem is here. even when I call prepareforincoming message it does not change the value of isMessage into true
        SoundDetails device = (SoundDetails) items.get(position);
        if (device != null) {
            TextView top = (TextView) v.findViewById(R.id.event_name);
            TextView bottom = (TextView) v.findViewById(R.id.event_time);
            Switch state = (Switch) v.findViewById(R.id.state);
            if (top != null) {
                top.setText(device.name);
            }
            if (bottom != null) {
                Date n = new Date();
                n.setTime(Long.parseLong(device.time));
                bottom.setText(n.getHours() +":"+n.getMinutes());
            }
            if (state != null)
                state.setChecked(device.IsEventActive);
                state.setTag(position);
        }
    } else{
            MessageListDetails MLD =  (MessageListDetails) items.get(position);
            TextView mainText;
            TextView subText;
            TextView messageTime;
            if(MLD != null){
             mainText = (TextView)convertView.findViewById(R.id.contactName);
             subText = (TextView) convertView.findViewById(R.id.contactNumber);
             messageTime = (TextView) convertView.findViewById(R.id.timeToSend);
             mainText.setText(MLD.contactName);
             subText.setText(MLD.contactNumber);
             Date n = new Date();
             n.setTime(Long.parseLong(MLD.sendingTime));
             messageTime.setText(n.getHours() +":"+n.getMinutes());
             isMessage = false;
            }
        } 
        return v;
    } 
} 
这就是完整的事件描述.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/timed_events_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:descendantFocusability="blocksDescendants"
     >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
        android:id="@+id/event_name"
        android:layout_width="wrap_content"
        android:layout_height="25dp"
        android:textSize="20sp"
        android:textStyle="bold"
        android:singleLine="true"
        />
        <TextView
        android:id="@+id/event_time"
        android:layout_width="wrap_content"
        android:layout_height="26dp"
        android:singleLine="true"
        />
    </LinearLayout>

    <Switch
        android:id="@+id/state"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:onClick="isActivated"
        />

</RelativeLayout>

这就是message_list_view.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="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/contactName"
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:textSize="20sp"
        android:textStyle="bold"
         />

    <TextView
        android:id="@+id/timeToSend"
        android:layout_width="wrap_content"
        android:layout_height="26dp"
        android:singleLine="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/contactName"
         />

    <TextView
        android:id="@+id/contactNumber"
        android:layout_width="match_parent"
        android:layout_height="26dp"
        android:layout_alignBaseline="@+id/timeToSend"
        android:layout_alignBottom="@+id/timeToSend"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/timeToSend"
         />

</RelativeLayout>


第一次生成视图时,ConvertView only==为空。此后,它不再为null,因此
if(isMessage==false)v=vi.inflate(R.layout.complete\u event\u description,null)永远不会被调用

您没有正确使用适配器接口。您永远不应该依赖getView()中的某个布尔值来确定这类事情——这就是适配器上的
viewType()
方法的作用。重写
BaseAdapter
并自己处理实现,这样会简单得多。解释如下:

public class TimedEventsAdapter extends BaseAdapter {
    private static final int VIEW_TYPE_COUNT = 2;
    private static final int VIEW_TYPE_MESSAGE = 0;
    private static final int VIEW_TYPE_SOUND = 1;

    private final List<Object> mItems;
    private final LayoutInflater mInflater;

    public TimedEventsAdapter(Context context, List<Object> objects) {
        mInflater = LayoutInflater.from(context);

        // Ensure that mItems is never null, even if a null object list
        // is received.
        mItems = new ArrayList<>();
        if (objects != null) {
            mItems.addAll(objects);
        }
    }

    @Override
    public int getCount() {
        return mItems.size();
    }

    @Override
    public Object getItem(int position) {
        // Just return the item in the appropriate position in the list
        return mItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        // Arbitrary value here since there is no unique identifier for the data
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int viewType = getItemViewType(position);

        // Initialize the View based on the view type (provided by getItemViewType())
        // Set a tag with an appropriate ViewHolder type to avoid findViewById() calls
        // on every iteration.
        if (convertView == null) {
           if (VIEW_TYPE_SOUND == viewType) {
               convertView = mInflater.inflate(R.layout.complete_event_description, parent, false);
               convertView.setTag(new SoundViewHolder(convertView));
           } else if (VIEW_TYPE_MESSAGE == viewType) {
               convertView = mInflater.inflate(R.layout.message_list_view, parent, false);
               convertView.setTag(new MessageViewHolder(convertView));
           }
        }

        // Update the View based on the view type. You know that you will have a non-null
        // View and appropriate ViewHolder set as a tag since that's been confirmed above.
        if (VIEW_TYPE_SOUND == viewType) {
            SoundDetails device = (SoundDetails) getItem(position);
            SoundViewHolder holder = (SoundViewHolder) convertView.getTag();

            holder.eventName.setText(device.name);
            holder.eventTime.setText(device.time);
            holder.state.setChecked(device.isEventActive);
            holder.state.setTag(position);
        } else if (VIEW_TYPE_MESSAGE == viewType) {
            MessageListDetails details = (MessageListDetails) getItem(position);
            MessageViewHolder holder = (MessageViewHolder) convertView.getTag();

            holder.contactName.setText(details.contactName);
            holder.contactNumber.setText(details.contactNumber);
            holder.timeToSend.setText(details.sendingTime);
        }

        return convertView;
    }

    @Override
    public int getViewTypeCount() {
        // Return the number of different view types to be eligible 
        // for View recycling.
        return VIEW_TYPE_COUNT;
    }

    @Override
    public int getItemViewType(int position) {
        // Figure out what type of data is at the given position.
        // instanceOf isn't very efficient -- it would be beter 
        // if the objects shared a base class that described what
        // they were, but for this example it will work.
        if (getItem(position) instanceof SoundDetails) {
            return VIEW_TYPE_SOUND;
        } else {
            return VIEW_TYPE_MESSAGE;
        }
    }

    //
    // Simple classes for holding references to views
    //

    private static class SoundViewHolder {
        final TextView eventName;
        final TextView eventTime;
        final Switch state;

        SoundViewHolder(View v) {
            eventName = (TextView) v.findViewById(R.id.event_name);
            eventTime = (TextView) v.findViewById(R.id.event_time);
            state = (Switch) v.findViewById(R.id.state);
        }
    }

    private static class MessageViewHolder {
        final TextView contactName;
        final TextView contactNumber;
        final TextView timeToSend;

        MessageViewHolder(View v) {
            contactName = (TextView) v.findViewById(R.id.contactName);
            contactNumber = (TextView) v.findViewById(R.id.contactNumber);
            timeToSend = (TextView) v.findViewById(R.id.timeToSend);
        }
    }
}
公共类TimedEventsAdapter扩展BaseAdapter{
私有静态最终整数视图类型计数=2;
私有静态最终整型视图\类型\消息=0;
私有静态最终int视图\类型\声音=1;
私人最终名单;
私人最终布局平面图;
public TimedEventsAdapter(上下文、列表对象){
mInflater=LayoutInflater.from(上下文);
//确保mItems从不为null,即使对象列表为null也是如此
//收到了。
mItems=新的ArrayList();
如果(对象!=null){
mItems.addAll(对象);
}
}
@凌驾
public int getCount(){
返回mItems.size();
}
@凌驾
公共对象getItem(int位置){
//只需将项目返回到列表中的适当位置即可
返回mItems.get(位置);
}
@凌驾
公共长getItemId(int位置){
//此处为任意值,因为数据没有唯一标识符
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
最终int viewType=getItemViewType(位置);
//基于视图类型初始化视图(由getItemViewType()提供)
//使用适当的ViewHolder类型设置标记以避免findViewById()调用
//在每次迭代中。
if(convertView==null){
如果(视图类型声音==视图类型){
convertView=mInflater.充气(R.layout.complete\u event\u description,parent,false);
setTag(新的SoundViewHolder(convertView));
}else if(视图类型消息==视图类型){
convertView=mInflater.充气(R.layout.message\u list\u视图,父视图,false);
setTag(新的MessageViewHolder(convertView));
}
}
//根据视图类型更新视图。您知道您将有一个非空的
//视图和相应的ViewHolder设置为标记,因为上面已经确认了这一点。
如果(视图类型声音==视图类型){
SoundDetails设备=(SoundDetails)getItem(位置);
SoundViewHolder=(SoundViewHolder)convertView.getTag();
holder.eventName.setText(device.name);
holder.eventTime.setText(device.time);
holder.state.setChecked(device.isEventActive);
holder.state.setTag(位置);
}else if(视图类型消息==视图类型){
MessageListDetails=(MessageListDetails)getItem(位置);
MessageViewHolder=(MessageViewHolder)convertView.getTag();
holder.contactName.setText(详细信息:contactName);
holder.contactNumber.setText(详细信息:contactNumber);
holder.timeToSend.setText(details.sendingTime);
}
返回视图;
}
@凌驾
public int getViewTypeCount(){
//返回要符合条件的不同视图类型的数目
//用于查看回收。
返回视图\类型\计数;
}
@凌驾
public int getItemViewType(int位置){
//找出给定位置的数据类型。
//instanceOf不是很有效——它会更有效
//如果对象共享一个描述了什么的基类
//是的,但对于这个例子来说,它会起作用。
if(getItem(position)声音细节实例){
返回视图\类型\声音;
}否则{
返回视图\类型\消息;
}
}
//
//用于保存对视图的引用的简单类
//
专用静态类SoundViewHolder{
最终文本视图事件名称;
最终文本视图事件时间;
最终开关状态;
SoundViewHolder(视图v){
eventName=(TextView)v.findViewById(R.id.event\u name);
eventTime=(TextView)v.findViewById(R.id.event\u time);
state=(开关)v.findviewbyd(R.id.state);
}
}
私有静态类MessageViewHolder{
最终文本视图联系人姓名;
最终文本视图联系人号码;
最终文本查看时间结束;
MessageViewHolder(视图v){
contactName=(TextView)v.findViewById(R.id.contactName);
contactNumber=(TextView)v.findViewById(R.id.contactNumber);
timeToSend=(TextView)v.findViewById(R.id.timeToSend);
}
}
}

ConvertView only在首次构建视图时为==null。此后,它不再为null,因此“if(isMessage==false)v=vi.inflate(R.layout.complete_event_description,null);”将永远不会出现called@Shadesblade你应该把它变成一个答案哦,对。最近我的评论有点太多了,呵呵。即使我重新开始
public class TimedEventsAdapter extends BaseAdapter {
    private static final int VIEW_TYPE_COUNT = 2;
    private static final int VIEW_TYPE_MESSAGE = 0;
    private static final int VIEW_TYPE_SOUND = 1;

    private final List<Object> mItems;
    private final LayoutInflater mInflater;

    public TimedEventsAdapter(Context context, List<Object> objects) {
        mInflater = LayoutInflater.from(context);

        // Ensure that mItems is never null, even if a null object list
        // is received.
        mItems = new ArrayList<>();
        if (objects != null) {
            mItems.addAll(objects);
        }
    }

    @Override
    public int getCount() {
        return mItems.size();
    }

    @Override
    public Object getItem(int position) {
        // Just return the item in the appropriate position in the list
        return mItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        // Arbitrary value here since there is no unique identifier for the data
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int viewType = getItemViewType(position);

        // Initialize the View based on the view type (provided by getItemViewType())
        // Set a tag with an appropriate ViewHolder type to avoid findViewById() calls
        // on every iteration.
        if (convertView == null) {
           if (VIEW_TYPE_SOUND == viewType) {
               convertView = mInflater.inflate(R.layout.complete_event_description, parent, false);
               convertView.setTag(new SoundViewHolder(convertView));
           } else if (VIEW_TYPE_MESSAGE == viewType) {
               convertView = mInflater.inflate(R.layout.message_list_view, parent, false);
               convertView.setTag(new MessageViewHolder(convertView));
           }
        }

        // Update the View based on the view type. You know that you will have a non-null
        // View and appropriate ViewHolder set as a tag since that's been confirmed above.
        if (VIEW_TYPE_SOUND == viewType) {
            SoundDetails device = (SoundDetails) getItem(position);
            SoundViewHolder holder = (SoundViewHolder) convertView.getTag();

            holder.eventName.setText(device.name);
            holder.eventTime.setText(device.time);
            holder.state.setChecked(device.isEventActive);
            holder.state.setTag(position);
        } else if (VIEW_TYPE_MESSAGE == viewType) {
            MessageListDetails details = (MessageListDetails) getItem(position);
            MessageViewHolder holder = (MessageViewHolder) convertView.getTag();

            holder.contactName.setText(details.contactName);
            holder.contactNumber.setText(details.contactNumber);
            holder.timeToSend.setText(details.sendingTime);
        }

        return convertView;
    }

    @Override
    public int getViewTypeCount() {
        // Return the number of different view types to be eligible 
        // for View recycling.
        return VIEW_TYPE_COUNT;
    }

    @Override
    public int getItemViewType(int position) {
        // Figure out what type of data is at the given position.
        // instanceOf isn't very efficient -- it would be beter 
        // if the objects shared a base class that described what
        // they were, but for this example it will work.
        if (getItem(position) instanceof SoundDetails) {
            return VIEW_TYPE_SOUND;
        } else {
            return VIEW_TYPE_MESSAGE;
        }
    }

    //
    // Simple classes for holding references to views
    //

    private static class SoundViewHolder {
        final TextView eventName;
        final TextView eventTime;
        final Switch state;

        SoundViewHolder(View v) {
            eventName = (TextView) v.findViewById(R.id.event_name);
            eventTime = (TextView) v.findViewById(R.id.event_time);
            state = (Switch) v.findViewById(R.id.state);
        }
    }

    private static class MessageViewHolder {
        final TextView contactName;
        final TextView contactNumber;
        final TextView timeToSend;

        MessageViewHolder(View v) {
            contactName = (TextView) v.findViewById(R.id.contactName);
            contactNumber = (TextView) v.findViewById(R.id.contactNumber);
            timeToSend = (TextView) v.findViewById(R.id.timeToSend);
        }
    }
}