开发者

Android ListView throwing NullPointerException when I try to scroll

Not exactly sure what is going on here so I am hoping one of you can point me in the right direction. I have a ListView within a Tab frame and for some reason, it loads but crashes when I try to scroll.

Here is all of the information I could gather

Here is the Activity that goes into the frame... it parses an XML file into a priority queue, gets the attached intent information, and loads the desired page.

public class QScoresFrameActivity extends ListActivity
{
private PriorityQueue<Score> mScores; 
private int mDifficulty;

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.s开发者_StackOverflowcoresframe);
    mDifficulty = getIntent().getIntExtra(getResources().getString(R.string.difficulty), getResources().getInteger(R.integer.normal_level));  
    mScores = QGameGlobals.ParseScoresXML(this,mDifficulty);
    setListAdapter(new ScoresAdapter(this));
}

private class ScoresAdapter extends BaseAdapter 
{
    private LayoutInflater mInflater;

    public ScoresAdapter(Context context) 
    {
        mInflater = LayoutInflater.from(context);
    }

    public View getView(int position, View convertView, ViewGroup parent) 
    {
        Score thisScore = mScores.getByIndex(position);
        convertView = mInflater.inflate(R.layout.scoreview, null);

        TextView posT;
        TextView nameT;
        TextView scoreT;

        String name = thisScore.getName();
        int score = thisScore.getScore();

        posT  = (TextView)convertView.findViewById(R.id.position);
        nameT = (TextView)convertView.findViewById(R.id.scorerName);
        scoreT= (TextView)convertView.findViewById(R.id.scorerScore);

        posT.setText(String.valueOf(position + 1) + ". ");
        nameT.setText(name);
        scoreT.setText(String.valueOf(score));

        return convertView;
    }

    public int getCount() 
    {
        return mScores.getLength();
    }

    public Object getItem(int position) 
    {
        return this;
    }

    public long getItemId(int position) 
    {
        return position;
    }
}

}

The layout file that holds the list:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:orientation="vertical">
    <ListView android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+android:id/list" />
</LinearLayout>

The layout file for each item in the list:

   <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linearLayout1" android:padding="10dp" android:layout_width="fill_parent" android:baselineAligned="false" android:orientation="horizontal" android:layout_height="wrap_content">
        <TextView android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="TextView" android:paddingRight="10dp" android:id="@+id/position" android:layout_width="50dp" android:textColor="@color/teal" ></TextView>
        <TextView android:id="@+id/scorerName" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="TextView" android:layout_width="wrap_content" android:layout_gravity="center_vertical"></TextView>
        <TextView android:id="@+id/scorerScore" android:text="TextView" android:textAppearance="?android:attr/textAppearanceLarge" android:paddingLeft="20dp" android:layout_height="wrap_content" android:gravity="right" android:textColor="@color/gold" android:layout_width="match_parent" android:layout_gravity="center_vertical"/>
</LinearLayout>

Priority Queue class....

@SuppressWarnings("rawtypes")
public class PriorityQueue<T extends Comparable> extends Queue<T>
{
public PriorityQueue ()
{
    super();
}

@SuppressWarnings("unchecked")
@Override
public void enqueue(T item)
/* Enqueue a new object of type T into the queue based on its compareTo method.
 * Sorts from greatest to least.
 */
{
    TNode newNode = new TNode(item);

    if (root == null)
    {
        root = newNode;
        end = newNode;
    }
    else
    {
        TNode currNode = root;
        TNode lastNode = root; 

        while (true)
        {
            int compVal = item.compareTo(currNode.get());

            if (compVal == 1 || compVal == 0)
            {
                if (currNode == root)
                {
                    root = newNode;
                }
                else
                {
                    lastNode.next = newNode;
                    newNode.next = currNode;
                }
                newNode.next = currNode;
                break;
            }
            else
            {
                if (currNode == end)
                {
                    currNode.next = newNode; 
                    end = newNode;
                    break;
                }
                else
                {
                lastNode = currNode;
                currNode = currNode.next;
                }
            }
        }
    }
    length++;
}
}

Appreciate the help.


A stack trace here would be most helpful. However, offhand, I would guess that the problem is you are storing the inflator in the adapter's constructor. Instead, just call getLayoutInflator() inside your getView() method. If that doesn't resolve it, please do post the logcat.


Just gonna guess because I ran into this when I started out with Android... I know the documentation says to name your list android:id="@+android:id/list" but try android:id="@id/android:list" instead also if it just so happens that you're starting with no info (empty list) define a view with android:id="@id/android:empty" as a placeholder.


The problem is with your getView() function in your custom listadapter (ScoreAdapter). When you scroll, the listview recycles your views and calls the getView() function. Change you getView() function to this to fix it:

public View getView(int position, View convertView, ViewGroup parent) 
{
    Score thisScore = mScores.getByIndex(position);
    if (convertView == null)
    {
        LayoutInflater mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = mInflater.inflate(R.layout.scoreview, null);
    }
    TextView posT;
    TextView nameT;
    TextView scoreT;

    String name = thisScore.getName();
    int score = thisScore.getScore();

    posT  = (TextView)convertView.findViewById(R.id.position);
    nameT = (TextView)convertView.findViewById(R.id.scorerName);
    scoreT= (TextView)convertView.findViewById(R.id.scorerScore);

    posT.setText(String.valueOf(position + 1) + ". ");
    nameT.setText(name);
    scoreT.setText(String.valueOf(score));

    return convertView;
}


Ahh yes, your problem is definitely in the PriorityQueue. That enqueue method is all sorts of broken, sorry. Get out a pencil and paper and walk through the scenarios of adding in the middle of the queue. I'm pretty certain that I see at least one bug, and possibly as many as three.

--randy

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜