我使用带有 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 后将其显示为 toast 来确定这一点。无论我点击哪一项,它总是显示列表中顶部项目的 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;
}
}