我正在尝试使用ProductHunt API在ListView中显示新帖子列表,并在点击时进一步展开列表项。
在打开应用程序时,会出现进度条,但之后应用程序屏幕保持空白。我认为我的OnPostExecute方法可能有一些错误,因为当我添加一个textview来显示一个字符串时,它会显示但是我的listView没有显示。
我使用标准的Apache HttpClient来处理api请求。
我有4个班级,
MainActivity.java
package com.emoji.apisoup;
/**
* Created by mdhalim on 16/05/16.
*/
import java.io.IOException;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import org.apache.http.HttpClientConnection;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.protocol.HTTP;
public class MainActivity extends Activity {
private ListView lvPosts;
private ProductHuntAdapter adapterPosts;
public static final String POST_DETAIL_KEY = "posts";
private ProgressDialog pDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.phunt_main);
String serverURL = "https://api.producthunt.com/v1/posts/";
ArrayList<ProductHuntList> aPosts = new ArrayList<ProductHuntList>();
adapterPosts = new ProductHuntAdapter(MainActivity.this, aPosts);
lvPosts = (ListView) findViewById(R.id.lvPosts);
lvPosts.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
{
Intent i = new Intent(MainActivity.this, ProductHuntDetail.class);
i.putExtra(POST_DETAIL_KEY, adapterPosts.getItem(position));
startActivity(i);
}
}
});
new LongOperation().execute(serverURL);
}
private class LongOperation extends AsyncTask<String, Void, Void> {
private final HttpClient Content = new DefaultHttpClient();
private String Error = null;
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
protected Void doInBackground(String... urls){
JSONArray items = null;
try {
HttpGet httpget = new HttpGet(urls[0]);
httpget.setHeader("Accept","application/json");
httpget.setHeader("Content-Type","application/json");
httpget.setHeader("Authorization","Bearer 2587aa878d7334e3c89794a6b73ebffb59a06c23b82cd0f789d2ab72d2417739");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String jsonStr = Content.execute(httpget, responseHandler);
Log.d("Response: ", "> " + jsonStr);
JSONObject jsonObj = new JSONObject(jsonStr);
items = jsonObj.getJSONArray("posts");
// Parse json array into array of model objects
ArrayList<ProductHuntList> posts = ProductHuntList.fromJson(items);
// Load model objects into the adapter
for (ProductHuntList post : posts) {
adapterPosts.add(post);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
Error = e.getMessage();
cancel(true);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
ArrayList<ProductHuntList> aPosts = new ArrayList<ProductHuntList>();
adapterPosts = new ProductHuntAdapter(MainActivity.this, aPosts);
lvPosts.setAdapter(adapterPosts);
}
}
}
ProductHuntList.java 包含JSON数据模型和反序列化器以及用于解析JSON数组的静态方法
package com.emoji.apisoup;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.io.Serializable;
/**
* Created by mdhalim on 18/05/16.
*/
public class ProductHuntList implements Serializable {
private static final long serialVersionUID = -8959832007991513854L;
private String name;
private String tagline;
private String screenshot_url;
private String largePosterUrl;
private String discussion_Url;
private String created_at;
private int votes_count;
public String getNames() {
return name;
}
public String getCreated_at() {
return created_at;
}
public String getScreenshot_url() {
return screenshot_url;
}
public String getDiscussion_Url() {
return discussion_Url;
}
public int getVotes_count() {
return votes_count;
}
public String getLargePosterUrl() {
return largePosterUrl;
}
public String getTagline(){
return tagline;
}
public static ProductHuntList fromJson(JSONObject jsonObject) {
ProductHuntList b = new ProductHuntList();
try {
// Deserialize json into object fields
b.name = jsonObject.getString("name");
b.created_at = jsonObject.getString("created_at");
b.tagline = jsonObject.getString("tagline");
b.screenshot_url = jsonObject.getJSONObject("screenshot_url").getString("300px");
b.largePosterUrl = jsonObject.getJSONObject("screenshot_url").getString("850px");
b.votes_count = jsonObject.getInt("votes_count");
b.discussion_Url = jsonObject.getString("discussion_url");
} catch (JSONException e) {
e.printStackTrace();
return null;
}
// Return new object
return b;
}
public static ArrayList<ProductHuntList> fromJson(JSONArray jsonArray) {
ArrayList<ProductHuntList> posts = new ArrayList<ProductHuntList>(jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject productJson = null;
try {
productJson = jsonArray.getJSONObject(i);
} catch (Exception e) {
e.printStackTrace();
continue;
}
ProductHuntList post = ProductHuntList.fromJson(productJson);
if (post != null)
{
posts.add(post);
}
}
return posts;
}
}
ProductHuntAdapter.java 这实现了ArrayAdapter
package com.emoji.apisoup;
/**
* Created by mdhalim on 18/05/16.
*/
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
/**
* Created by mdhalim on 18/05/16.
*/
public class ProductHuntAdapter extends ArrayAdapter<ProductHuntList> {
public ProductHuntAdapter(Context context, ArrayList<ProductHuntList> aPosts) {
super(context, 0, aPosts);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
ProductHuntList posts = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.item_product_hunt, null);
}
// Lookup view for data population
TextView name = (TextView) convertView.findViewById(R.id.name);
TextView created = (TextView) convertView.findViewById(R.id.created);
TextView tagline = (TextView) convertView.findViewById(R.id.tagline);
ImageView ivPosterImage = (ImageView) convertView.findViewById(R.id.ivPosterImage);
// Populate the data into the template view using the data object
name.setText(posts.getNames());
created.setText("Created On: " + posts.getCreated_at() + "%");
tagline.setText(posts.getTagline());
Picasso.with(getContext()).load(posts.getScreenshot_url()).into(ivPosterImage);
// Return the completed view to render on screen
return convertView;
}
}
最后,当用户点击列表中的任何项目时,实现项目详细信息活动的类。 ProductHuntDetail
package com.emoji.apisoup;
/**
* Created by mdhalim on 18/05/16.
*/
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.text.Html;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
public class ProductHuntDetail extends Activity {
private ImageView ivPosterImage;
private TextView name;
private TextView discusUrl;
private TextView upvotes;
private TextView tagline;
private TextView created;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.product_hunt_detail);
// Fetch views
ivPosterImage = (ImageView) findViewById(R.id.ivPosterImage);
name = (TextView) findViewById(R.id.name);
discusUrl = (TextView) findViewById(R.id.discusUrl);
created = (TextView) findViewById(R.id.created);
upvotes = (TextView) findViewById(R.id.upvotes);
tagline = (TextView) findViewById(R.id.tagline);
// Load movie data
ProductHuntList posts = (ProductHuntList) getIntent().getSerializableExtra(MainActivity.POST_DETAIL_KEY);
loadMovie(posts);
}
// Populate the data for the movie
@SuppressLint("NewApi")
public void loadMovie(ProductHuntList posts) {
// Populate data
name.setText(posts.getNames());
upvotes.setText(Html.fromHtml("<b>Upvotes:</b> " + posts.getVotes_count() + "%"));
created.setText(posts.getCreated_at());
tagline.setText(posts.getTagline());
discusUrl.setText(Html.fromHtml("<b>Discussion Url:</b> " + posts.getDiscussion_Url()));
// R.drawable.large_movie_poster from
// http://content8.flixster.com/movie/11/15/86/11158674_pro.jpg -->
Picasso.with(this).load(posts.getLargePosterUrl()).
placeholder(R.drawable.large_movie_poster).
into(ivPosterImage);
}
}
我一直试图调试这几个小时:/
答案 0 :(得分:0)
您的异步任务正在返回空白。
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
ArrayList<ProductHuntList> aPosts = new ArrayList<ProductHuntList>();
adapterPosts = new ProductHuntAdapter(MainActivity.this, aPosts);
lvPosts.setAdapter(adapterPosts);
}
据我所知,代码中的aPosts是空的。
我认为你的异步任务应该是 -
AsyncTask<String, Void, ProductHuntAdapter>
并删除 -
adapterPosts = new ProductHuntAdapter(MainActivity.this, aPosts);
您正在使用doInBackground()
方法创建并更新此内容。
答案 1 :(得分:0)
我明白了!
我不需要在onPostExecute()方法中再次声明这些行
ArrayList<ProductHuntList> aPosts = new ArrayList<ProductHuntList>();
adapterPosts = new ProductHuntAdapter(MainActivity.this, aPosts);
所以基本上,我的新onPostExecute()方法就像这样
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
lvPosts.setAdapter(adapterPosts);
}
我过去2个小时一直试图找到这个错误,因此更难,我甚至没有收到任何错误。一旦我在StackOverFlow上发布它,似乎我有神圣的干预。