滚动时ListView崩溃

时间:2014-05-05 12:40:30

标签: android listview android-listview

我对ListView有一点问题。当然,这是我做错了,我找不到答案,我想知道是否有人可以指出我的错误,并帮助我解决它。

问题是我正在为行创建一个具有两种不同布局的ListView。一个是仅包含文本的行,另一个是包含文本和图像的布局。只有具有数据的数组的最后四个值将是与图像一起使用第二个布局的值。

加载活动时ListView正确显示,并且行已正确设置单击操作。我可以向下滚动列表,但当我向上滚动时,应用程序停止并引发以下错误:

05-05 12:30:46.574    1532-1532/com.xxx.xxx.app E/InputEventReceiver﹕ Exception dispatching input event.
05-05 12:30:46.574    1532-1532/com.xxx.xxx.app E/MessageQueue-JNI﹕ Exception in MessageQueue callback: handleReceiveCallback
05-05 12:30:46.578    1532-1532/com.xxx.xxx.app E/MessageQueue-JNI﹕ java.lang.NullPointerException
            at com.xxx.xxx.app.LawyersActivity$LawyersAdapter.getView(LawyersActivity.java:246)
        at android.widget.AbsListView.obtainView(AbsListView.java:2240)
        at android.widget.ListView.makeAndAddView(ListView.java:1790)
        at android.widget.ListView.fillDown(ListView.java:691)
        at android.widget.ListView.correctTooLow(ListView.java:1467)
        at android.widget.ListView.fillGap(ListView.java:665)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5136)
        at android.widget.AbsListView.onGenericMotionEvent(AbsListView.java:3804)
        at android.view.View.dispatchGenericMotionEventInternal(View.java:7801)
        at android.view.View.dispatchGenericMotionEvent(View.java:7782)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchGenericMotionEvent(PhoneWindow.java:2076)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchGenericMotionEvent(PhoneWindow.java:1525)
        at android.app.Activity.dispatchGenericMotionEvent(Activity.java:2494)
        at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchGenericMotionEvent(ActionBarActivityDelegateICS.java:278)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchGenericMotionEvent(PhoneWindow.java:2030)
        at android.view.View.dispatchPointerEvent(View.java:7888)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3954)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3833)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3525)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3582)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5602)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5582)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5553)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5682)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:138)
        at android.os.Looper.loop(Looper.java:123)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at c
05-05 12:30:46.582    1532-1532/com.xxx.xxx.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.xxx.xxx.app, PID: 1532
java.lang.NullPointerException
        at com.xxx.xxx.app.LawyersActivity$LawyersAdapter.getView(LawyersActivity.java:246)
        at android.widget.AbsListView.obtainView(AbsListView.java:2240)
        at android.widget.ListView.makeAndAddView(ListView.java:1790)
        at android.widget.ListView.fillDown(ListView.java:691)
        at android.widget.ListView.correctTooLow(ListView.java:1467)
        at android.widget.ListView.fillGap(ListView.java:665)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5136)
        at android.widget.AbsListView.onGenericMotionEvent(AbsListView.java:3804)
        at android.view.View.dispatchGenericMotionEventInternal(View.java:7801)
        at android.view.View.dispatchGenericMotionEvent(View.java:7782)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1824)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1777)
        at android.view.View.dispatchGenericMotionEvent(View.java:7775)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchGenericMotionEvent(PhoneWindow.java:2076)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchGenericMotionEvent(PhoneWindow.java:1525)
        at android.app.Activity.dispatchGenericMotionEvent(Activity.java:2494)
        at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchGenericMotionEvent(ActionBarActivityDelegateICS.java:278)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchGenericMotionEvent(PhoneWindow.java:2030)
        at android.view.View.dispatchPointerEvent(View.java:7888)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3954)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3833)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3525)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3582)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3449)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3426)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3399)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5602)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5582)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5553)
        at         
android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5682)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:138)
        at android.os.Looper.loop(Looper.java:123)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.and

我用于自定义适配器的代码如下。变量大小具有必须使用第一个布局设置的数组部分的计数(除了最后一个布局之外的所有部分)。

public final static String EXTRA_MESSAGE = "com.xxx.xxx.MESSAGE";
public final static String WEB_URL = "http://www.test.com";
public final static String CONTACT_EMAIL = "email@email.com";
public final static String EMAIL_SUBJECT = "Text";

ArrayList<Lawyer> lawyers = new ArrayList<Lawyer>();
String categorie = null;
int size;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    categorie = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

    setContentView(R.layout.activity_lawyers);

    XmlPullParserFactory pullParserFactory;
    try {
        pullParserFactory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = pullParserFactory.newPullParser();

        InputStream in_s = getResources().getAssets().open("lawyers.xml");
        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(in_s, null);

        parseXML(parser);

    } catch (XmlPullParserException e) {

        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    size = lawyers.size();

    Lawyer auxLawer = new Lawyer();
    auxLawer.caseName = "Who are we?";
    auxLawer.icon = "icons_list_07";
    lawyers.add(auxLawer);

    auxLawer = new Lawyer();
    auxLawer.caseName = "Call now";
    auxLawer.icon = "icons_list_08";
    lawyers.add(auxLawer);

    auxLawer = new Lawyer();
    auxLawer.caseName = "Check our web";
    auxLawer.icon = "icons_list_09";
    lawyers.add(auxLawer);

    auxLawer = new Lawyer();
    auxLawer.caseName = "Text us";
    auxLawer.icon = "icons_list_10";
    lawyers.add(auxLawer);

    LawyersAdapter adapter = new LawyersAdapter(this);

    ListView lstOpciones = (ListView) findViewById(R.id.listViewLawyers);
    lstOpciones.setAdapter(adapter);

    lstOpciones.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> a, View v, int position, long id) {

            if (position < size) {
                Intent intent = new Intent(LawyersActivity.this, CaseDetailActivity.class);
                intent.putExtra("Lawyer", lawyers.get(position));
                LawyersActivity.this.startActivity(intent);
            } else if (position == size) {
                Intent intent = new Intent(LawyersActivity.this, MiAppActivity.class);
                LawyersActivity.this.startActivity(intent);
               } else if (position == (size + 1)) { //LLamar
                Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + R.string.phone_number));
                LawyersActivity.this.startActivity(intent);
            } else if (position == (size + 2)) { //Web
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(WEB_URL));
                LawyersActivity.this.startActivity(intent);
            } else if (position == (size + 3)) { //Email
                Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
                        "mailto", CONTACT_EMAIL, null));
                emailIntent.putExtra(Intent.EXTRA_SUBJECT, EMAIL_SUBJECT);
                LawyersActivity.this.startActivity(Intent.createChooser(emailIntent, "Enviar email..."));
            }

        }
    });
}

private void parseXML(XmlPullParser parser) throws XmlPullParserException,IOException {

    int eventType = parser.getEventType();
    Lawyer currentLawyer = null;

    while (eventType != XmlPullParser.END_DOCUMENT) {
        String name = null;
        switch (eventType) {
            case XmlPullParser.START_DOCUMENT:
                break;
            case XmlPullParser.START_TAG:
                name = parser.getName();
                if (name.equals("lawyer")) {
                    currentLawyer = new Lawyer();
                } else if (currentLawyer != null) {
                    if (name.equals("categorie")) {
                        currentLawyer.categorie = parser.nextText();
                    } else if (name.equals("type")) {
                        currentLawyer.type = parser.nextText();
                    } else if (name.equals("case")) {
                        currentLawyer.caseName = parser.nextText();
                    } else if (name.equals("description")) {
                        currentLawyer.description = parser.nextText();
                    } else if (name.equals("advise")) {
                        currentLawyer.advise = parser.nextText();
                    } else if (name.equals("empresas")) {
                        currentLawyer.empresas = parser.nextText();
                    } else if (name.equals("trabajadores")) {
                        currentLawyer.trabajadores = parser.nextText();
                    }
                }

                break;
            case XmlPullParser.END_TAG:
                name = parser.getName();
                if (name.equalsIgnoreCase("lawyer") && currentLawyer != null){
                    if (currentLawyer.categorie.equalsIgnoreCase(categorie)) {
                        lawyers.add(currentLawyer);
                    }
                }
                break;
        }
        eventType = parser.next();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.lawyers, menu);

    MenuItem item = menu.findItem(R.id.action_settings);
    item.setVisible(false);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

class LawyersAdapter extends ArrayAdapter {

    Activity context;

    LawyersAdapter(Activity context){
        super(context, R.layout.list_item_lawyer, lawyers);
        this.context = context;
    }

    public int getItemViewType(int position) {
        if (position < size) {
            return 0;
        } else {
            return 1;
        }
    }

    public int getViewTypeCount() {
        return 2;
    }

    public View getView(int position, View convertView, ViewGroup parent){
        View item = convertView;
        ViewHolder holder;
        ViewHolderImage holderImage;

        if (getItemViewType(position) == 0) {
            if (item == null) {
                LayoutInflater inflater = context.getLayoutInflater();
                item = inflater.inflate(R.layout.list_item_lawyer, null);

                holder = new ViewHolder();
                holder.titulo = (TextView) item.findViewById(R.id.titleLawyer);

                item.setTag(holder);
            } else {
                holder = (ViewHolder) item.getTag();
            }

            holder.titulo.setText(lawyers.get(position).caseName);
        } else {
            if (item == null) {
                LayoutInflater inflater = context.getLayoutInflater();
                item = inflater.inflate(R.layout.list_item_categories, null);
                holderImage = new ViewHolderImage();
                holderImage.titulo = (TextView) item.findViewById(R.id.titleCategory);
                holderImage.imagen = (ImageView)item.findViewById(R.id.imageCategory);
            } else {
                holderImage = (ViewHolderImage) item.getTag();
            }
245
246            holderImage.titulo.setText(lawyers.get(position).caseName);
247            String uri = "drawable/" + lawyers.get(position).icon;

            int imageResource = getResources().getIdentifier(uri, null, getPackageName());

            Drawable image = getResources().getDrawable(imageResource);

            holderImage.imagen.setImageDrawable(image);
        }

        return(item);
    }

}

static class ViewHolder {
    TextView titulo;
}

static class ViewHolderImage {
    TextView titulo;
    ImageView imagen;
}

我将适配器设置到视图中的方式是:

LawyersAdapter adapter = new LawyersAdapter(this);
ListView lstOptions = (ListView) findViewById(R.id.listViewLawyers);
lstOptions.setAdapter(adapter);

提前致谢。

更新1:包含活动的完整代码。

1 个答案:

答案 0 :(得分:0)

最后,我能够使用LayoutInflater获得解决方案。由于我没有太多使用Android的经验,我认为我一直在搞乱代码实现以实现它。

这是适合我的适配器代码。我希望它可以帮助其他人。

感谢您的评论。

class LawyersAdapter extends ArrayAdapter<Lawyer> {

    private final Context context;

    LawyersAdapter(Context context){
        super(context, R.layout.list_item_lawyer, lawyers);
        this.context = context;
    }

    public int getItemViewType(int position) {
        if (position < size) {
            return 0;
        } else {
            return 1;
        }
    }

    public int getViewTypeCount() {
        return 2;
    }

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

        ViewHolder holder = null;
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        int type = getItemViewType(position);
        if (convertView == null) {
            holder = new ViewHolder();
            switch (type) {
                case 0:
                    convertView = mInflater.inflate(R.layout.list_item_lawyer, null);
                    holder.title = (TextView)convertView.findViewById(R.id.titleLawyer);
                    break;
                case 1:
                    convertView = mInflater.inflate(R.layout.list_item_categories, null);
                    holder.title = (TextView)convertView.findViewById(R.id.titleCategory);
                    holder.image = (ImageView)convertView.findViewById(R.id.imageCategory);
                    break;
                default:
                    break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }
        holder.title.setText(lawyers.get(position).caseName);

        if (type == 1) {
            String uri = "drawable/" + lawyers.get(position).icon;

            int imageResource = getResources().getIdentifier(uri, null, getPackageName());

            Drawable image = getResources().getDrawable(imageResource);

            holder.image.setImageDrawable(image);
        }

        return convertView;

    }

}

static class ViewHolder {
    TextView title;
    ImageView image;
}