带有Parse Query Adapter / ListView的view.findViewById()上的NullPointerException

时间:2014-11-28 05:58:55

标签: android android-listview nullpointerexception parse-platform android-parsequeryadapter

我使用带有Parse Query Adapter的自定义适配器填充了ListView。我的问题是,我似乎只能访问列表的第一项。在ListView中,我有一个我想调用函数的按钮。

    android:id="@+id/showGrunts"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_below="@id/buttonthang"
    android:clickable="true"
    android:onClick="displayGruntList"

这是点击按钮时调用的功能:

public void displayGruntList(View view) {
    TextView objectID = (TextView) findViewById(R.id.tvPostIDCheese);

    String id = objectID.getText().toString();

    //String id = ((TextView)(view.findViewById(R.id.tvPostIDCheese))).getText().toString();

    Intent i = new Intent(GruntrMain.this, GruntList.class);
    Bundle idData = new Bundle();
    idData.putString("id", id);
    i.putExtras(idData);
    startActivity(i);
}

注意注释行。我的问题是,如果我单击此按钮,它将只显示ListView的第一项的相关项,即使我单击列表中不同项的按钮。我已经能够通过在获得ID后将ID显示为吐司来确定。无论我点击哪一个,它总是显示列表中顶部项目的ID。如果我对它们进行重新排序,并且通过在每个列表项中显示ID,我仍然可以确信它在我的查询中不是问题,因为它们都显示了正确的ID。

我对传递给函数的视图的理解是它来自正在被选中的实际项目。我已经看过其他使用view.findViewById()的代码,但是当我尝试这个时,该行给了我一个NullPointerException。我想要做的是从TextView中获取该特定项目的文本(表示ID)。再次,使用我目前拥有的代码,它只能从第一个项目中获取该文本。所以问题不在我的Parse查询中,而在于我如何访问它。发生此问题的整个.java文件可以在下面看到。

package com.snowflakes.gruntr;

import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseQueryAdapter;
import com.parse.ParseRelation;
import com.parse.ParseUser;

public class GruntrMain extends Activity {

private static final int LOGIN_REQUEST = 0;

private ListView listView;
private ParseQueryAdapter<ParseObject> mainAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gruntr_main);

    ImageView addF = (ImageView) findViewById(R.id.ivAddFriend);
    final ImageView fReq = (ImageView) findViewById(R.id.ivFriendRequest);
    ImageView mPost = (ImageView) findViewById(R.id.ivMakePost);

    mainAdapter = new CustomAdapter(this);

    listView = (ListView) findViewById(R.id.lvPostList);
    listView.setAdapter(mainAdapter);
    mainAdapter.loadObjects();

    Thread refreshFeed = new Thread() {
        public void run() {
            while (true) {

                try {
                    sleep(20000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {

                    mainAdapter.loadObjects();
                }

            }
        }// public void run()
    }; // new Thread()
    refreshFeed.start();

    // This thread is used for friend polling
    // In order to get it to run repeatedly, may need to make an infinite
    // loop
    // If a friend request is found to be pending, it will cause a button to
    // appear, allowing you to accept the friend request
    // For later implementation, this can be refined
    // For example: It can cause the notification area to show that you have
    // a friend request pending
    // Also, the ability to deny friend requests is already built in. I'll
    // actually code that in when it become relevant
    // -- Aaron
    Thread friendRequestPolling = new Thread() {
        public void run() {
            while (true) {

                try {
                    sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {

                    ParseUser user = ParseUser.getCurrentUser();
                    ParseQuery<ParseObject> friendQuery = ParseQuery
                            .getQuery("FriendRequests");
                    friendQuery.whereEqualTo("Recipient", user);

                    friendQuery
                            .getFirstInBackground(new GetCallback<ParseObject>() {
                                public void done(ParseObject request,
                                        ParseException e) {
                                    if (request != null) {
                                        fReq.setImageResource(R.drawable.friendrequesttrue);
                                    } else {
                                        fReq.setImageResource(R.drawable.friendrequest);
                                    }

                                }
                            });

                }

            }
        }// public void run()
    }; // new Thread()
    friendRequestPolling.start();

    Thread friendAcceptedPolling = new Thread() {
        public void run() {
            while (true) {

                try {
                    sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {

                    ParseUser user = ParseUser.getCurrentUser();
                    ParseQuery<ParseObject> friendQuery = ParseQuery
                            .getQuery("FriendRequests");
                    friendQuery.whereEqualTo("Sender", user);
                    friendQuery.whereEqualTo("Accepted", "true");

                    friendQuery
                            .findInBackground(new FindCallback<ParseObject>() {
                                public void done(
                                        List<ParseObject> returnedUsers,
                                        ParseException e) {
                                    for (ParseObject currentUser : returnedUsers) {
                                        if (currentUser != null) {
                                            ParseUser user = ParseUser
                                                    .getCurrentUser();
                                            ParseRelation<ParseUser> relation = user
                                                    .getRelation("friends");
                                            relation.add(currentUser
                                                    .getParseUser("Recipient"));
                                            user.saveInBackground();
                                            currentUser
                                                    .deleteInBackground();
                                        }

                                    }
                                }
                            });

                }

            }
        }// public void run()
    }; // new Thread()
    friendAcceptedPolling.start();

    mPost.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Intent i = new Intent(GruntrMain.this, MakePost.class);
            startActivity(i);
        }
    });

    addF.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Intent i = new Intent(GruntrMain.this, AddFriend.class);
            startActivity(i);

        }
    });

    fReq.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Intent i = new Intent(GruntrMain.this, FriendRequests.class);
            startActivity(i);
        }
    });

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == LOGIN_REQUEST) {
        if (resultCode == RESULT_OK) {
            Intent i = new Intent(GruntrMain.this, GruntrMain.class);
            i.putExtra("User", ParseUser.getCurrentUser().getString("name"));
            startActivity(i);
            finish();
        } else {
            Intent i = new Intent(GruntrMain.this, Goodbye.class);
            startActivity(i);
            finish();
        }
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main_menu, menu);
    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;
    } else if (id == R.id.action_logout) {
        ParseUser.logOut();
        ParseUser currentUser = ParseUser.getCurrentUser();

        ParseLoginBuilder builder = new ParseLoginBuilder(GruntrMain.this);
        Intent parseLoginIntent = builder
                .setAppLogo(R.drawable.orangebanner)
                .setParseLoginEnabled(true)
                .setParseLoginButtonText("Go")
                .setParseSignupButtonText("Register")
                .setParseLoginHelpText("Forgot password?")
                .setParseLoginInvalidCredentialsToastText(
                        "Your email and/or password is not correct")
                .setParseLoginEmailAsUsername(true)
                .setParseSignupSubmitButtonText("Submit registration")
                .build();
        startActivityForResult(parseLoginIntent, 0);
    } else if (id == R.id.action_post) {
        Intent i = new Intent(GruntrMain.this, MakePost.class);
        startActivity(i);
    }
    return super.onOptionsItemSelected(item);
}

public void displayGruntList(View view) {
    TextView objectID = (TextView) findViewById(R.id.tvPostIDCheese);

    String id = objectID.getText().toString();

    // String id =
    // ((TextView)(view.findViewById(R.id.tvPostIDCheese))).getText().toString();

    Intent i = new Intent(GruntrMain.this, GruntList.class);
    Bundle idData = new Bundle();
    idData.putString("id", id);
    i.putExtras(idData);
    startActivity(i);
}

public void gruntAtIt(View view) {

    TextView objectID = (TextView) findViewById(R.id.tvPostIDCheese);

    String id = objectID.getText().toString();

    ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Post");

    query.whereEqualTo("objectId", id);

    ParseObject post = null;

    try {
        post = query.getFirst();
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (post != null) {
            post.increment("Grunts");
            post.saveInBackground();
        }
    }

    Intent i = new Intent(GruntrMain.this, RecordGrunt.class);
    Bundle idData = new Bundle();
    idData.putString("id", id);
    i.putExtras(idData);
    startActivity(i);

}

}

这里是CustomAdapter.java,在那里进行查询并填充列表。

package com.snowflakes.gruntr;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.parse.ParseFile;
import com.parse.ParseImageView;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseQueryAdapter;
import com.parse.ParseRelation;
import com.parse.ParseUser;

public class CustomAdapter extends ParseQueryAdapter<ParseObject> {


public CustomAdapter(Context context) {
    // Use the QueryFactory to construct a PQA that will only show
    // Todos marked as high-pri
    super(context, new ParseQueryAdapter.QueryFactory<ParseObject>() {
        public ParseQuery create() {

            ParseUser user = ParseUser.getCurrentUser();

            ParseRelation<ParseUser> relation = user.getRelation("friends");
            ParseQuery friendsQuery = relation.getQuery();

            ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Post");
            query.whereMatchesQuery("CreatedBy", friendsQuery);
            query.addDescendingOrder("createdAt");
            return query;
        }
    });
}

// Customize the layout by overriding getItemView
@Override
public View getItemView(ParseObject object, View v, ViewGroup parent) {
    if (v == null) {
        v = View.inflate(getContext(), R.layout.individual_post, null);
    }

    super.getItemView(object, v, parent);

    // Add and download the image
    ParseImageView todoImage = (ParseImageView) v.findViewById(R.id.icon);
    ParseFile imageFile = object.getParseFile("Image");
    if (imageFile != null) {
        todoImage.setParseFile(imageFile);
        todoImage.loadInBackground();
    }

    // Add the title view
    TextView titleTextView = (TextView) v.findViewById(R.id.text1);
    titleTextView.setText(object.get("Name").toString());

    // Add a reminder of how long this item has been outstanding
    TextView timestampView = (TextView) v.findViewById(R.id.timestamp);
    timestampView.setText(object.getCreatedAt().toString());

    TextView objectID = (TextView) v.findViewById(R.id.tvPostIDCheese);
    objectID.setText(object.getObjectId());

    TextView gruntCount = (TextView) v.findViewById(R.id.showGrunts);
    gruntCount.setText("Show Grunts (" + object.getNumber("Grunts") + ")");


    return v;
}



}

1 个答案:

答案 0 :(得分:0)

传递给onClick的视图参数只是单击的视图,而不是周围的布局。除非tvPostIDCheese是您按钮的子视图,否则无法以这种方式访问​​它。

而是尝试在适配器的getItemView期间使用gruntCount.setTag(object.getObjectId())将对象ID存储在可点击的视图中。然后在displayGruntList中使用(String)view.getTag()检索它。

有关详细信息,请参阅setTaggetTag