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