Я прошел ваш код и обнаружил некоторые проблемы.
Некоторые плохие практики, которые я нашел в вашем коде:
- Вы добавляете свои URL в отдельный список со спецификатором
static
. Вместо этого вы должны добавить переменную url в вашу модель News
напрямую. И вы можете напрямую получить всю модель New
внутри ListView > setOnItemClickListener
.
- Вы создаете
Bitmap
для всех ваших изображений. Это может вызвать OOM Exception
. Вместо этого вы должны использовать любую библиотеку загрузки изображений.
Я исправил все проблемы и создал рабочий код. Пожалуйста, внесите необходимые изменения, которые вы хотите на вашем конце.
HealthNews.java
public class HealthNews extends AppCompatActivity {
private Context context;
private NewsAdapter mNewsAdapter;
private ArrayList<News> listNews;
private static final String REQUEST_URL = "https://newsapi.org/v2/top-headlines?country=in&category=health&apiKey=3f7d99cdbb004766892bd239a4c099be";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.health_news);
context = this;
ListView list_news = findViewById(R.id.list_news);
listNews = new ArrayList<>();
mNewsAdapter = new NewsAdapter(context, listNews);
list_news.setAdapter(mNewsAdapter);
list_news.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
try {
News selNews = (News) parent.getAdapter().getItem(position);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(selNews.getUrl())));
} catch (Exception e) {
// Missing 'http://' or 'https://' will cause crash
e.printStackTrace();
}
}
});
new NewsAsyncTask().execute(REQUEST_URL);
}
private class NewsAsyncTask extends AsyncTask<String, Void, ArrayList<News>> {
private ProgressDialog p;
@Override
public void onPreExecute() {
super.onPreExecute();
p = new ProgressDialog(context);
p.setMessage("Latest News...");
p.setIndeterminate(false);
p.show();
}
@Override
public ArrayList<News> doInBackground(String... urls) {
return QueryUtils.fetchEarthquakeData(urls[0]);
}
@Override
public void onPostExecute(ArrayList<News> newsList) {
super.onPostExecute(newsList);
listNews.addAll(newsList);
p.hide();
mNewsAdapter.notifyDataSetChanged();
}
}
}
QueryUtils.java
public class QueryUtils {
public static ArrayList<News> fetchEarthquakeData(String apiUrl) {
ArrayList<News> listNews = new ArrayList<>();
try {
URL url = new URL(apiUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000);
conn.setConnectTimeout(60000);
conn.setRequestMethod("GET");
conn.connect();
int responseCode = conn.getResponseCode();
InputStream iStream;
if (responseCode == HttpURLConnection.HTTP_OK)
iStream = conn.getInputStream();
else
iStream = conn.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
String jsonResponse = response.toString();
if (TextUtils.isEmpty(jsonResponse))
return null;
JSONObject jsonObject1 = new JSONObject(jsonResponse);
JSONArray baseJSONArray = jsonObject1.getJSONArray("articles");
for (int i = 0; i < baseJSONArray.length(); i++) {
JSONObject jsonObject = baseJSONArray.getJSONObject(i);
JSONObject source = jsonObject.getJSONObject("source");
News news = new News();
news.setArticle(jsonObject.optString("title"));
news.setUrl(jsonObject.optString("url"));
news.setUrlToImage(jsonObject.optString("urlToImage"));
listNews.add(news);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return listNews;
}
}
News.java (модель)
public class News {
private String article;
private String url;
private String urlToImage;
public News() {
this.article = "";
this.url = "";
this.urlToImage = "";
}
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
}
NewsAdapter.java (измените макет элемента в соответствии с вашим кодом)
public class NewsAdapter extends BaseAdapter {
private Context context;
private LayoutInflater mInflater;
private List<News> listNews;
public NewsAdapter(Context context, List<News> listNews) {
this.context = context;
this.listNews = listNews;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return listNews.size();
}
@Override
public News getItem(int position) {
return listNews.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
private ImageView item_img_news;
private TextView item_txt_article;
}
@SuppressLint("InflateParams")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_news, null);
holder = new ViewHolder();
holder.item_img_news = convertView.findViewById(R.id.item_img_news);
holder.item_txt_article = convertView.findViewById(R.id.item_txt_article);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final News news = getItem(position);
holder.item_txt_article.setText(news.getArticle());
Glide.with(context).load(news.getUrlToImage()).into(holder.item_img_news);
return convertView;
}
}
app> build.gradle
implementation 'com.github.bumptech.glide:glide:4.9.0'