草庐IT

android - 当变量不为空时,自定义适配器的 getview 抛出 NullPointerException

coder 2023-12-11 原文

我正在尝试设置自定义适配器以使用 ListView 上的演示聊天应用程序向用户显示消息,但在我的自定义列表适配器的 getView 方法中收到错误。

  • 我仔细检查了我的步骤并进行了调试,以了解 holder 是否 不为空。但是 holder 不是 null 正如你在我的调试器中看到的那样 可变输出。

在线错误:

holder.message.setText("lol");

我的自定义适配器的 getView() 可能有什么错误?感谢您提前提供任何提示和帮助。

我的自定义适配器:

import java.util.ArrayList;

import android.content.Context;
import android.support.v4.view.ViewPager.LayoutParams;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ChattingAdapter extends BaseAdapter{
    private Context mContext;
    private ArrayList<ChatMessage> mMessages;


    public ChattingAdapter(Context context, ArrayList<ChatMessage> messages) {
        super();
        this.mContext = context;
        this.mMessages = messages;
    }
    @Override
    public int getCount() {
        return mMessages.size();
    }
    @Override
    public Object getItem(int position) {       
        return mMessages.get(position);
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ChatMessage message = (ChatMessage) this.getItem(position);

        ViewHolder holder; 
        if(convertView == null)
        {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.listener, parent, false);
            holder.message = (TextView) convertView.findViewById(R.id.text1);
            convertView.setTag(holder);
        }
        else
            holder = (ViewHolder) convertView.getTag();
        Log.wtf("message", message.getMessage());
        //holder.message.setText(message.getMessage());
        holder.message.setText("lol");
        LayoutParams lp = (LayoutParams) holder.message.getLayoutParams();      

        //Check whether message is mine to show green background and align to right

        if(message.isMine())

        {
                holder.message.setBackgroundResource(R.drawable.speech_bubble_green);
                lp.gravity = Gravity.RIGHT;

        }
        //If not mine then it is from sender to show orange background and align to left

        else

        {

            holder.message.setBackgroundResource(R.drawable.speech_bubble_orange);          
            lp.gravity = Gravity.LEFT;

        }
            holder.message.setLayoutParams(lp);
            //holder.message.setTextColor(R.color.textColor);   

        return convertView;
    }
    private static class ViewHolder
    {
        TextView message;
    }

    @Override
    public long getItemId(int position) {
        //Unimplemented, because we aren't using Sqlite.
        return position;
    }

}

我的变量调试器结果:

holder  ChattingAdapter$ViewHolder  (id=830019560368)   
this    ChattingAdapter  (id=830019493992)  
message ChatMessage  (id=830019492960)  
position    0   
convertView LinearLayout  (id=830019561504) 
parent  ListView  (id=830018556296)

我的 Xml 布局: 列表项.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/text1"
  android:background="@drawable/speech_bubble_green"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:singleLine="false"
  android:textStyle="bold" />

监听器.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:orientation="vertical"
  android:padding="10dip" 
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

    <ListView
      android:id="@android:id/list"
      android:layout_width="wrap_content" 
      android:layout_height="0px" 
      android:layout_weight="1"
       android:transcriptMode="normal"
      android:stackFromBottom="true"
      android:fadingEdge="none" android:padding="4dp"
      android:fastScrollEnabled="true" android:smoothScrollbar="false"
      android:focusable="true"/>

      <LinearLayout android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:orientation="horizontal"
        android:gravity="center_vertical"
        android:padding="4dp">

         <EditText android:id="@+id/chat_input"
           android:layout_width="0dip"
           android:layout_height="fill_parent"
           android:layout_weight="1"
           android:maxLines="5"
           android:inputType="textShortMessage|textAutoCorrect|textMultiLine|textCapSentences"
           android:imeOptions="actionSend|flagNoExtractUi" 
           android:cursorVisible="true"
           android:hint="Enter message" />

         <Button android:id="@+id/chat_send_message"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="send" />

        </LinearLayout>


</LinearLayout>

我的堆栈跟踪:

02-21 16:48:36.008: E/Trace(18696): error opening trace file: No such file or directory (2)
02-21 16:49:00.008: A/Service(18696): connected
02-21 16:52:07.508: A/message(18696): Hello
02-21 16:52:26.018: E/AndroidRuntime(18696): FATAL EXCEPTION: main
02-21 16:52:26.018: E/AndroidRuntime(18696): java.lang.NullPointerException
02-21 16:52:26.018: E/AndroidRuntime(18696):    at com.example.konnect.ChattingAdapter.getView(ChattingAdapter.java:49)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.AbsListView.obtainView(AbsListView.java:2273)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.ListView.makeAndAddView(ListView.java:1769)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.ListView.fillUp(ListView.java:706)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.ListView.layoutChildren(ListView.java:1626)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.AbsListView.onLayout(AbsListView.java:2108)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.View.layout(View.java:13754)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewGroup.layout(ViewGroup.java:4364)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.View.layout(View.java:13754)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewGroup.layout(ViewGroup.java:4364)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.View.layout(View.java:13754)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewGroup.layout(ViewGroup.java:4364)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.View.layout(View.java:13754)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewGroup.layout(ViewGroup.java:4364)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.View.layout(View.java:13754)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewGroup.layout(ViewGroup.java:4364)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1868)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1689)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.Choreographer.doFrame(Choreographer.java:525)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.os.Handler.handleCallback(Handler.java:615)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.os.Handler.dispatchMessage(Handler.java:92)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.os.Looper.loop(Looper.java:137)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at android.app.ActivityThread.main(ActivityThread.java:4931)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at java.lang.reflect.Method.invokeNative(Native Method)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at java.lang.reflect.Method.invoke(Method.java:511)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
02-21 16:52:26.018: E/AndroidRuntime(18696):    at dalvik.system.NativeStart.main(Native Method)
02-21 16:52:31.008: E/Trace(18898): error opening trace file: No such file or directory (2)

在添加新消息时调用自定义适配器的函数:

ArrayList<ChatMessage> messagex= new ArrayList<ChatMessage>();;
ChattingAdapter adaptex;
@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.listener);
messagex.add(new ChatMessage("Hello", false));
adaptex  = new ChattingAdapter(getApplicationContext(),messagex);
setListAdapter(adaptex);
Button send_button = (Button) findViewById(R.id.chat_send_message);
sender_message = (EditText) findViewById(R.id.chat_input);
send_button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        msg = sender_message.getText().toString();
        if(!(msg.length()==0)){
            messagex.add(new ChatMessage(msg, true));
            //addNewMessage(new ChatMessage(msg, true));
            adaptex.notifyDataSetChanged();
            getListView().setSelection(messagex.size()-1);
               }
        }});

聊天消息类:

public class ChatMessage {

    String message;
    /**
     * boolean to determine, who is sender of this message
     */
    boolean isMine;

    //  boolean isStatusMessage;

        /**
         * Constructor to make a Message object
         */
        public ChatMessage(String message, boolean isMine) {
            super();
            this.message = message;
            this.isMine = isMine;
        //  this.isStatusMessage = false;
        }
        /**
         * Constructor to make a status Message object
         * consider the parameters are swaped from default Message constructor,
         *  not a good approach but have to go with it.
         */
        public ChatMessage(boolean status, String message) {
            super();
            this.message = message;
            this.isMine = false;
            //this.isStatusMessage = status;
        }
        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
        public boolean isMine() {
            return isMine;
        }
        public void setMine(boolean isMine) {
            this.isMine = isMine;
        }
        /**
        public boolean isStatusMessage() {
            return isStatusMessage;
        }
        public void setStatusMessage(boolean isStatusMessage) {
            this.isStatusMessage = isStatusMessage;
        }
        */
}

最佳答案

你有

convertView = LayoutInflater.from(mContext).inflate(R.layout.listener, parent, false);

然后

holder.message = (TextView) convertView.findViewById(R.id.text1);

但是您在 listitem.xml 中有 id text1 的 textview,而不是您膨胀的 listener.xml

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/text1"

因此你初始化失败

holder.message = (TextView) convertView.findViewById(R.id.text1);

因此 NullPointerException @

holder.message.setText("lol");

解决方案:改为

convertView = LayoutInflater.from(mContext).inflate(R.layout.listitem, parent, false);

关于android - 当变量不为空时,自定义适配器的 getview 抛出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21933372/

有关android - 当变量不为空时,自定义适配器的 getview 抛出 NullPointerException的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  4. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  7. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  8. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  9. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  10. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

随机推荐