由BaseAdapter子类的getView方法创建的视图的生命周期

时间:2012-11-04 21:24:51

标签: android android-layout android-widget

我遇到与自定义适配器为常见ListView创建的视图生命周期相关的问题。我创建了一个自定义视图,如下所示:

    public class NSViewZoneLarge extends RelativeLayout
    {
        private long mZoneId;
        private ToggleButton mOnOffButton;

        public NSViewZoneLarge(Context context, boolean showSwitch, long zoneId)
        {
            super(context);
            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            layoutInflater.inflate(R.layout.view_zone_large, this);
            mOnOffButton = (ToggleButton) findViewById(R.id.toggleButtonOnOff);

            ImageView imgView = (ImageView)findViewById(R.id.imageViewZoneType);
            imgView.setFocusable(false);

            if (showSwitch)
            {
                mOnOffButton.setVisibility(View.VISIBLE);
            }
            else
            {
                mOnOffButton.setVisibility(View.INVISIBLE);
                mOnOffButton.setEnabled(false);
                mOnOffButton.setFocusable(false);
                mOnOffButton.setFocusableInTouchMode(false);
            }

            mZoneId = zoneId;
        }

        // ---------------------------------------------------------------------------------------
        public NSViewZoneLarge(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }

        // ---------------------------------------------------------------------------------------
        public void setZoneName(String zoneName)
        {
            TextView tVZoneName = (TextView) findViewById(R.id.textViewZoneName);
            tVZoneName.setText(zoneName);
        }

        // ---------------------------------------------------------------------------------------
        public String getZoneName()
        {
            TextView tVZoneName = (TextView) findViewById(R.id.textViewZoneName);
            return tVZoneName.getText().toString();
        }

        // ---------------------------------------------------------------------------------------
        public void setOnOffButton(boolean isOn)
        {
            ToggleButton onOffButton = (ToggleButton) findViewById(R.id.toggleButtonOnOff);
            onOffButton.setChecked(isOn);
        }

        // ---------------------------------------------------------------------------------------
        public boolean isOnOffButtonChecked()
        {
            ToggleButton onOffButton = (ToggleButton) findViewById(R.id.toggleButtonOnOff);
            return onOffButton.isChecked();
        }

        // ---------------------------------------------------------------------------------------
        public long getZoneId()
        {
            return mZoneId;
        }
}

然后我在getView()子类的BaseAdapter方法中实例化此视图:

// ---------------------------------------------------------------------------------------
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    NSDestinationContent destinationContent = mDestinationContents.get(position);
    NSViewZoneLarge viewZone = new NSViewZoneLarge(mContext, mShowSwitches, destinationContent.mDestinationContentId);

    viewZone.setZoneName(destinationContent.mName);

    if (mShowSwitches)
        viewZone.setOnOffButton(mOnOffStates.get(position));

    if (destinationContent.mDestinationTypeId.equals(DestinationTypeId.SPEAKERS_GROUP))
    {
        NSSpeakerGroup speakerGroup = (NSSpeakerGroup) destinationContent;
        viewZone.setZoneType(speakerGroup.mZoneTypeId);
    }

    return viewZone;
}

最后,我为OnItemLongClickListener设置了listView

    mZonesListView.setOnItemLongClickListener(new OnItemLongClickListener()
    {
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
        {
            NSViewZoneLarge viewZoneLarge = (NSViewZoneLarge)view;
            long destinationId = viewZoneLarge.getZoneId();
            ClipData data = ClipData.newPlainText(NSConstants.DRAG_KEY_ZONE_ID, String.valueOf(destinationId));

            view.startDrag(data, new DragShadowBuilder(view), null, 0);

            Intent intent = new TrashBinIntent(true);
            LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(ApplicationNetSpeaker.getInstance());
            localBroadcastManager.sendBroadcast(intent);

            return true;
        }
    });

问题是方法getZoneId()总是返回null,尽管我正确地通过NSViewZoneLarge方法中的getView()构造函数设置了这个值。

我知道它为什么返回null;这是因为OnItemLongClickListener给了我一个NSViewZoneLarge的实例,它不是getView()方法创建的实例。在某个地方,NSViewZoneLarge实例仅使用第二个 - 默认构造函数创建。

我还尝试使用setTag()方法将数据与视图相关联,但getTag()方法始终返回null - 同样,原始实例在某处丢失,可能是由GC发布的,我得到了一个没有设置标签的新实例。

有人可以解释一下为什么会发生这种情况吗?如何将任何类型的数据与ListView项目的特定视图相关联?

0 个答案:

没有答案