I know that this question has been asked before but none of the solutions worked for me. I have a ViewPager in a TabLayout with fragments for each of the tabs. Now, each of those fragments has a RecyclerView that gets data from the internet and only the first RecyclerView is populated. I can't figure out how I'm messing up. I know it's just because I'm not using it right but I can't really figure out how. I'd really appreciate some help.
It looks like this where the second tab is just empty:
Here's my code:
Code
MainActivity.java
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.Style;
public class MainActivity extends AppCompatActivity {
private MapView mapView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Mapbox Access token
Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_api_key));
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(Style.DARK, style -> {
}));
ViewPager2 pager = findViewById(R.id.view_pager);
ViewPageAdapter pageAdapter = new ViewPageAdapter(getSupportFragmentManager(), getLifecycle());
pager.setAdapter(pageAdapter);
pager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
TabLayout tabLayout = findViewById(R.id.tabLayout2);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
new StatsLoader("https://api.covid19api.com/summary", pageAdapter, pager, tabLayout).execute();
new NewsLoader("https://newsapi.org/v2/top-headlines?q=coronavirus&sortBy=popularity", pageAdapter, pager, tabLayout).execute();
}
}
SortJSONArray.java
import android.util.Log;
import org.json.JSONObject;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class SortJsonArray {
void sortArray(List list, final String keyName, final boolean ascending) {
Collections.sort(list, new Comparator<JSONObject>() {
private final String KEY_NAME = keyName;
#Override
public int compare(JSONObject o1, JSONObject o2) {
String val1 = "";
String val2 = "";
try {
val1 = String.valueOf(o1.get(KEY_NAME));
val2 = String.valueOf(o2.get(KEY_NAME));
} catch (Exception e) {
Log.e("Sort Exception", "Issue when sorting JSONArray", e);
e.printStackTrace();
}
if (IntCheckHelper.isInteger(val1)) {
if (ascending) {
return Integer.valueOf(val1).compareTo(Integer.valueOf(val2));
}
else {
return Integer.valueOf(val2).compareTo(Integer.valueOf(val1));
}
}
else {
if (ascending) {
return val1.compareToIgnoreCase(val2);
}
else {
return val2.compareToIgnoreCase(val1);
}
}
}
});
}
}
StatsFragment.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;
public class StatsFragment extends Fragment {
View view;
RecyclerView recyclerView;
JSONArray covidData;
String dataUrl;
public StatsFragment(JSONArray data, String url) {
covidData = data;
dataUrl = url;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.view_page, container, false);
recyclerView = view.findViewById(R.id.recyclerView2);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(false);
RecyclerView.Adapter<CustomListAdapter.ListViewHolder> mAdapter = new CustomListAdapter(covidData, dataUrl);
recyclerView.setAdapter(mAdapter);
return view;
}
}
CustomListAdapter.java
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;
import org.json.JSONException;
import java.text.NumberFormat;
public class CustomListAdapter extends RecyclerView.Adapter<CustomListAdapter.ListViewHolder> {
private JSONArray mDataset;
private String murl;
static class ListViewHolder extends RecyclerView.ViewHolder {
TextView textView;
TextView textView2;
ImageView imageView;
ListViewHolder(LinearLayout v) {
super(v);
textView = v.findViewById(R.id.name);
textView2 = v.findViewById(R.id.cases);
imageView = v.findViewById(R.id.image);
}
}
CustomListAdapter(JSONArray myDataset, String url) {
mDataset = myDataset;
murl = url;
}
#NonNull
#Override
public CustomListAdapter.ListViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_view, parent, false);
// TextView v = (TextView) linearLayout.findViewById(R.id.info_text);
return new ListViewHolder(linearLayout);
}
#Override
public void onBindViewHolder(ListViewHolder holder, int position) {
String textViewString = "";
String textView2String = "";
try {
if (murl.contains("api.covid19api.com")) {
textViewString = mDataset.getJSONObject(position).getString("Country");
textView2String = NumberFormat.getInstance().format(mDataset.getJSONObject(position).getInt("TotalConfirmed"));
}
else if (murl.contains("newsapi.org")) {
textViewString = mDataset.getJSONObject(position).getString("title");
textView2String = mDataset.getJSONObject(position).getString("description");
}
holder.textView.setText(textViewString);
holder.textView2.setText(textView2String);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return mDataset.length();
}
}
StatsLoader.java
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.net.ssl.HttpsURLConnection;
public class StatsLoader extends AsyncTask<String, Void, JSONArray> {
Exception exception;
String urlString = "";
static JSONArray covidData = new JSONArray();
ViewPageAdapter pageAdapter;
ViewPager2 viewPager2;
TabLayout tabLayout;
public StatsLoader(String url, ViewPageAdapter adapter, ViewPager2 pager, TabLayout tabs) {
super();
urlString = url;
pageAdapter = adapter;
viewPager2 = pager;
tabLayout = tabs;
}
#Nullable
#Override
public JSONArray doInBackground(String ... urls) {
HttpsURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(urlString);
connection = (HttpsURLConnection) url.openConnection();
connection.connect();
InputStream inputStream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder buffer = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
covidData = json.getJSONArray("Countries");
ArrayList<Object> list = new ArrayList<>();
for (int i = 0; i < covidData.length(); i++) {
list.add(covidData.get(i));
}
SortJsonArray sortJsonArray = new SortJsonArray();
sortJsonArray.sortArray(list, "TotalConfirmed", false);
covidData = new JSONArray();
for (Object object : list) {
covidData.put(object);
}
return covidData;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(JSONArray coviddata) {
if (this.exception == null) {
Log.d("Check", "Works!");
pageAdapter.addFragment(new StatsFragment(coviddata, urlString), "Stats");
viewPager2.setAdapter(pageAdapter);
new TabLayoutMediator(tabLayout, viewPager2,
(tab, position) -> {
switch (position) {
case 0:
tab.setText("Stats");
break;
case 1:
tab.setText("News");
break;
case 2:
tab.setText("Symptoms");
break;
case 3:
tab.setText("Safety");
break;
default:
break;
}
}).attach();
}
}
}
ViewPageAdapter.java
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
public class ViewPageAdapter extends FragmentStateAdapter {
private final ArrayList<Fragment> fragments = new ArrayList<>();
private final ArrayList<String> titles = new ArrayList<>();
public ViewPageAdapter(#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
public void addFragment(Fragment fragment, String title) {
fragments.add(fragment);
titles.add(title);
}
#NonNull
#Override
public Fragment createFragment(int position) {
return fragments.get(position);
}
#Override
public int getItemCount() {
return fragments.size();
}
}
NewsFragment.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;
public class NewsFragment extends Fragment {
View view;
RecyclerView recyclerView;
JSONArray news;
String newsUrl;
public NewsFragment(JSONArray data, String url) {
news = data;
newsUrl = url;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.view_page, container, false);
recyclerView = view.findViewById(R.id.recyclerView2);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(false);
RecyclerView.Adapter<CustomListAdapter.ListViewHolder> mAdapter = new CustomListAdapter(news, newsUrl);
recyclerView.setAdapter(mAdapter);
return view;
}
}
NewsLoader.java
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class NewsLoader extends AsyncTask<String, Void, JSONArray> {
Exception exception;
String urlString = "";
static JSONArray news = new JSONArray();
ViewPageAdapter pageAdapter;
ViewPager2 viewPager2;
TabLayout tabLayout;
public NewsLoader(String url, ViewPageAdapter adapter, ViewPager2 pager, TabLayout tabs) {
super();
urlString = url;
pageAdapter = adapter;
viewPager2 = pager;
tabLayout = tabs;
}
#Nullable
#Override
public JSONArray doInBackground(String ... urls) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(urlString);
connection = (HttpsURLConnection) url.openConnection();
connection.addRequestProperty("Authorization", "Bearer baef544b7dbe4ff8b15bb502d1fd5e1a");
connection.connect();
InputStream inputStream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder buffer = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
news = json.getJSONArray("articles");
return news;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(JSONArray newsData) {
if (this.exception == null) {
Log.d("Check", "Works!");
pageAdapter.addFragment(new NewsFragment(newsData, urlString), "News");
viewPager2.setAdapter(pageAdapter);
new TabLayoutMediator(tabLayout, viewPager2,
(tab, position) -> {
switch (position) {
case 0:
tab.setText("Stats");
break;
case 1:
tab.setText("News");
break;
case 2:
tab.setText("Symptoms");
break;
case 3:
tab.setText("Safety");
break;
default:
break;
}
}).attach();
}
}
}
Layouts
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:statusBarScrim="#null"
app:titleEnabled="false"
android:minHeight="?attr/actionBarSize" >
<fragment
android:id="#+id/mapView"
android:name="com.mapbox.mapboxsdk.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="350sp"
android:apiKey="#string/mapbox_api_key"
android:clickable="true"
android:enabled="true"
android:focusable="true"
app:layout_collapseMode="parallax" />
<androidx.appcompat.widget.Toolbar
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="48dp"
android:gravity="top"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark"
app:title="" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent">
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
tools:listitem="#layout/view_page" >
</androidx.viewpager2.widget.ViewPager2>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
list_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="14sp"
android:layout_margin="15sp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="40sp">
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/name"
android:layout_toStartOf="#+id/name"
android:contentDescription="Image of country flag" />
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10sp" />
<TextView
android:id="#+id/cases"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/name" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
view_page.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
tools:listitem="#layout/list_view">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
API Key
pk.eyJ1IjoiZGF5ZW1zYWVlZCIsImEiOiJja2E2d3FyZTYwZHh5MnptdzFjcXMycTRxIn0.hpzQHB9-_OTMC1iGkkvYpw
The issue is with the NewsFragment and NewsLoader section of the code since that's the one not showing up. I added the rest for context in case anyone needs it. Thank you!
Edit: Added the SortJSONArray code and API key as per the comment suggestion.
just fix your layout...data is there only
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:listitem="#layout/list_view">
</androidx.recyclerview.widget.RecyclerView>
remove:
app:layout_constraintTop_toBottomOf="parent"
Related
The images are being downloaded in RecipeApiActivity - I can see them in a test ImageView called 'imigiview', so the API Request works! But I want them to be displayed correctly in a recyclerview - now it shows nothing at all.
For that I created a list of Bitmaps in which I put all the downloaded bitmaps, this list is given to the RecipeAPIAdapter that should place them in the RecyclerView.
Can you help me find out why the images are not shown? ( The Logcat gives me no error of any kind)
package byDragosT.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Map;
// Aceasta activitate detine o lista de retete gasita pe spoontacular bagata in recyclerview//
// Va lua un RecipeItem si il va baga in RecipeApiAdapter si apoi il conecteaza la recyclerview
public class RecipeAPIActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecipeApiAdapter adapter;
// private TextView jsonUnparsedResult;
private ImageView imigiView;
private ArrayList<Bitmap> images = new ArrayList<>(8);
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_api);
String url1 = "flour"; // just for simplifying the stackOverflow question I put this value here
String url2 = "egg"; // just for simplifying the stackOverflow question I put this value here
String url3 = "salt"; // just for simplifying the stackOverflow question I put this value here
String urlfinal = "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/findByIngredients?number=5&ranking=1&ignorePantry=false&ingredients=" + url1 + url2 + url3;
System.out.println(urlfinal);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(urlfinal)
.get()
.addHeader("x-rapidapi-host", "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com")
.addHeader("x-rapidapi-key", "key hidden")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(final Response response) throws IOException {
if (response.isSuccessful()){
//Aici inca suntem pe background thread - metoda enqueue -- //
final String myResponse;
myResponse = response.body().string();
// Aici trecem pe threadul principal din nou //
RecipeAPIActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// jsonUnparsedResult.setText(myResponse);
System.out.println(myResponse);
try {
JSONArray results = new JSONArray(myResponse);
if(results.length() > 0){
for (int i = 0; i < results.length(); i++){
JSONObject object = results.getJSONObject(i);
// jsonUnparsedResult.setText(object.getString("title"));
System.out.println(object.getString("image"));
// SPRITES
String imgUrl = object.getString("image"); // aici sprites e Obiect cu 8 perechi key-values
new DownloadSpriteTask().execute(imgUrl);
}
}
} catch (JSONException e) { e.printStackTrace(); }
}
});
}
}
});
imigiView = findViewById(R.id.imaginedetest); // on post execute at Asynktask
recyclerView = findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
// System.out.println("ce se intampla" + images);
adapter = new RecipeApiAdapter(images);
recyclerView.setAdapter(adapter);
// jsonUnparsedResult = findViewById(R.id.JsonExample);
}
private class DownloadSpriteTask extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
return BitmapFactory.decodeStream(url.openStream());
} catch (IOException e) {
Log.e("cs50", "Download sprite error", e);
return null;
}
}
#Override
protected void onPostExecute(Bitmap bitmap) {
imigiView.setImageBitmap(bitmap);
images.add(bitmap); /// images e facut sa ia int ca valoare nu Bitmap
System.out.println("Another photo attached!");
}
}
/// Ingredients should be comma separated //// symbol for ',' is %252C
//// symbol for space ' ' is %20 //
public String urlify (String ingredient, String vitamina){
String theUrl = "";
if (ingredient.equals("Choose a " + vitamina + " ingredient")){
System.out.println("VA RUGAM sa introduceti ceva ok !!!!!!!!!!");
ingredient = "";
}else{
String[] splitResult = ingredient.split(" ",8);
for (String word:splitResult){
if (word.equals("-")){
theUrl = theUrl + "%252C";
break;
}else theUrl = theUrl + word + "%20";
}
}
return theUrl;
}
}
RecipeAPIAdapter
package byDragosT.myapplication;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class RecipeApiAdapter extends RecyclerView.Adapter<RecipeApiAdapter.RecipeViewHolder> {
private ArrayList<Bitmap> images;
public RecipeApiAdapter(ArrayList<Bitmap> images){
this.images = images;
}
public static class RecipeViewHolder extends RecyclerView.ViewHolder {
public ImageView pozaReteta;
public TextView titlu;
public TextView descriere;
RecipeViewHolder(View view){
super(view);
pozaReteta = view.findViewById(R.id.poza);
titlu = view.findViewById(R.id.recipe_name);
descriere = view.findViewById(R.id.ingredients_list);
}
}
#NonNull
#Override //// Mare grija ce layout pui aici - sfat pentru viitor - mi-a luat 4 ore sa gasesc eroarea
public RecipeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_item_in_recyclerview_api, parent, false);
RecipeViewHolder recipeViewHolder = new RecipeViewHolder(view);
return recipeViewHolder;
}
#Override
public void onBindViewHolder(#NonNull RecipeViewHolder holder, int position) {
Bitmap image_id = images.get(position);
holder.pozaReteta.setImageBitmap(image_id);
holder.titlu.setText("Image: "+ position);
}
#Override
public int getItemCount() {
return images.size();
}
}
activity_recipe_api.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RecipeAPIActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<TextView
android:id="#+id/JsonExample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="150dp"
android:layout_marginBottom="8dp"
android:text="Testing testing 123"
android:background="#color/colorPrimaryDark"
android:textColor="#android:color/background_light"
app:layout_constraintStart_toEndOf="#+id/recyclerView" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imaginedetest"
android:contentDescription="#string/imagine_de_test" />
</RelativeLayout>
recipe_item_in_recyclerview_api.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<ImageView
android:id="#+id/poza"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="4dp"
android:layout_marginEnd="2dp"
android:paddingTop="10dp"
app:layout_constraintEnd_toStartOf="#+id/ingredients_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#android:drawable/sym_def_app_icon" />
<TextView
android:id="#+id/recipe_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:text="#string/mankarika_super"
android:textAlignment="center"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.52"
app:layout_constraintStart_toEndOf="#+id/poza"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/ingredients_list"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:text="Se face din: ceapa, apa, si multe multe multe multe multe multe multe multe multe multe multe multe chestii"
android:textAlignment="gravity"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/poza"
app:layout_constraintTop_toBottomOf="#+id/recipe_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
For image loading by far the easiest is using either Picasso or Glide.
Honestly, I have no idea how to do it without using those libs :)
I need to parse json and show them on RecyclerView.. But my RecyclerView isn't working..
I need to fix this..
This is Json
Simple Json File for My app
[
{
"name": "Saif Maroof",
"roll": 978617,
"gender":"Male",
"phonenumber": 01931078639,
"StudentImage": "R.drawble.books"
},
{
"name": "Minhaj",
"roll": 978617,
"gender":"Male",
"phonenumber": 01931078639,
"studentimage": "R.drawble.books"
}
]
This is StudentInfo Activity
I think in this activity nothing gets wrong
package com.college.npc17_18.activity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import com.college.npc17_18.MainActivity;
import com.college.npc17_18.R;
import com.college.npc17_18.adapter.StudentInfoAdapter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class StudentInfo extends AppCompatActivity {
RecyclerView recyclerView;
StudentInfoAdapter studentInfoAdapter;
RecyclerView.Adapter adapter;
// ProgressBar progressBar;
RecyclerView.LayoutManager layoutManager;
List <Object> studentInfo = new ArrayList<>();
DividerItemDecoration dividerItemDecoration;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_student_info);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// progressBar = findViewById(R.id.progress_circular_country);
recyclerView = findViewById(R.id.studentsInfoRecycleView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new StudentInfoAdapter(this,studentInfo);
// String jsonFileString = Utils.getJsonFromAssets(getApplicationContext(), "studentinfo.json");
// progressBar.setVisibility(View.GONE);
// studentInfoAdapter = new StudentInfoAdapter(this,studentInfo);
recyclerView.setAdapter(adapter);
addItemsFromJSON();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
private void addItemsFromJSON() {
try {
String jsonDataString = readJSONDataFromFile();
JSONArray jsonArray = new JSONArray(jsonDataString);
for (int i=0; i<jsonArray.length(); ++i) {
JSONObject itemObj = jsonArray.getJSONObject(i);
String name = itemObj.getString("name");
String roll = itemObj.getString ("roll");
String phonenumber = itemObj.getString("phonenumber");
String gender = itemObj.getString("gender");
int studentimage = itemObj.getInt("studentimage");
com.college.npc17_18.model.StudentInfo studentInfos = new com.college.npc17_18.model.StudentInfo(name,roll,phonenumber,gender,studentimage);
studentInfo.add(studentInfos);
}
} catch (JSONException | IOException e) {
Log.d(TAG, "addItemsFromJSON: ", e);
}
}
private String readJSONDataFromFile() throws IOException{
InputStream inputStream = null;
StringBuilder builder = new StringBuilder();
try {
String jsonString = null;
inputStream = getResources().openRawResource(R.raw.studentinfo);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream, "UTF-8"));
while ((jsonString = bufferedReader.readLine()) != null) {
builder.append(jsonString);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return new String(builder);
}
}
This is StudentInfo Adapter
package com.college.npc17_18.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.college.npc17_18.R;
import com.college.npc17_18.model.StudentInfo;
import java.util.ArrayList;
import java.util.List;
public class StudentInfoAdapter extends RecyclerView.Adapter <StudentInfoAdapter.Viewholder> {
private List <Object> studentInfos;
Context context;
public StudentInfoAdapter(Context context, List<Object> studentInfo) {
this.studentInfos = studentInfo;
this.context = context;
}
#NonNull
#Override
public StudentInfoAdapter.Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.studentitem,parent,false);
return new Viewholder(view);
}
#Override
public void onBindViewHolder(#NonNull StudentInfoAdapter.Viewholder holder, int position) {
StudentInfo studentInfo = (StudentInfo) studentInfos.get(position);
holder.StudentImageId.setImageResource (studentInfo.getStudentImage());
holder.NameId.setText("Name:"+studentInfo.getNamme());
holder.RollId.setText("Roll"+studentInfo.getRoll());
holder.GenderId.setText("Gender:"+studentInfo.getGender());
holder.PhoneNumberId.setText("Phone Number:"+studentInfo.getPhoneNumber());
}
#Override
public int getItemCount() {
return studentInfos.size();
}
public class Viewholder extends RecyclerView.ViewHolder{
TextView NameId,RollId,PhoneNumberId,GenderId;
ImageView StudentImageId;
public Viewholder(#NonNull View itemView) {
super(itemView);
StudentImageId = itemView.findViewById(R.id.StudentImageId);
NameId = itemView.findViewById(R.id.NameId);
RollId = itemView.findViewById(R.id.RollId);
// CGPAId = itemView.findViewById(R.id.CGPAId);
GenderId = itemView.findViewById(R.id.GenderId);
PhoneNumberId = itemView.findViewById(R.id.PhoneNumberId);
}
}
}
This is StudentItem.xml
Layout for RecyclerView...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:clickable="true"
android:elevation="40dp"
app:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<ImageView
android:id="#+id/StudentImageId"
android:layout_width="71dp"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:id="#+id/NameId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="18sp" />
<TextView
android:id="#+id/RollId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Roll" />
<TextView
android:id="#+id/GenderId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Gender" />
<TextView
android:id="#+id/PhoneNumberId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Phone Number" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
Now what do I need to do?
At the time when you instantiate an object of your adapter class
adapter = new StudentInfoAdapter(this,studentInfo);
Your adapter object is initialized with an empty studentInfo list
So, you should call adapter.notifyDataSetChanged(); in your addItemsFromJSON() method when the JSON parsing is completed.
update your adapter after you set your data
yourAdapter.notifyDataSerChanged();
I am developing a basic quiz app but stuck in API part. In the API, we have a "question", "choices", "choice" and "correct" keywords. I want to keep "question" and "choice" keywords' values in an array or different arrays, add fragment as long as question number, also add these questions and choices to fragment activity. I shared a sample screenshot of how it should look like. Layour is not important that much, I need Java code only.If you can help me, I would be grateful. Thank you.
Click for screenshot
This is my MainActivity.java
package myusarisoy.quizmasters;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
Frag frag = new Frag();
ViewPager vp;
RequestQueue requestQueue;
String[] abc, cba;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vp = findViewById(R.id.vp);
requestQueue = Volley.newRequestQueue(this);
FragmentPagerAdapter fpa = new FragmentPagerAdapter(getSupportFragmentManager()) {
#Override
public Fragment getItem(final int position) {
String url = "https://private-anon-a98702efdd-quizmasters.apiary-mock.com/questions";
final JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
for(int i = 0; i < response.length(); i++) {
JSONObject jrResponse = response.getJSONObject(i);
String question = jrResponse.getString("question");
abc = new String[question.length()];
JSONArray choiceArray = jrResponse.getJSONArray("choices");
for(int j = 0; j < choiceArray.length(); j++) {
JSONObject currentChoice = choiceArray.getJSONObject(j);
String choice = currentChoice.getString("choice");
cba = new String[choice.length()];
String q = abc[i];
String c = cba[j];
Bundle b = new Bundle() ;
b.putString("tvQ", q);
b.putString("tvC", c);
frag.setArguments(b);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("myusarisoy", "Error...");
}
});
requestQueue.add(request);
return frag;
}
#Override
public int getCount() {
return abc.length;
}
};
// Set PagerAdapter to ViewPager
vp.setAdapter(fpa);
}
public void importantTask() {
Log.e("myusarisoy", "Important Task...");
}
}
This my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
This my Frag.java
package myusarisoy.quizmasters;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Frag extends Fragment {
View root;
TextView tvQuestion, tvChoices;
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.activity_frag, container, false);
tvQuestion = root.findViewById(R.id.tvq);
tvChoices = root.findViewById(R.id.tvc);
String tvQ = getArguments().getString("tvQ");
String tvC = getArguments().getString("tvC");
tvQuestion.setText(tvQ);
tvChoices.setText(tvC);
MainActivity ma = (MainActivity) getActivity();
ma.importantTask();
return root;
}
}
This is my activity_frag.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Frag">
<TextView
android:layout_marginTop="200sp"
android:id="#+id/tvq"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20sp"
android:textColor="#000000"
android:textStyle="bold"
android:text="Question"
android:gravity="center"/>
<TextView
android:layout_marginTop="50sp"
android:id="#+id/tvc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="17sp"
android:textColor="#000000"
android:textStyle="bold"
android:text="Answers"
android:gravity="center"/>
</LinearLayout>
I think you got this a bit backwards.
You'll need to get the questions, then build a list of Fragments, then build an adapter.
That would look like this
// directly in onCreate
final List<Frag> frags = new ArrayList<>();
String url = "https://private-anon-a98702efdd-quizmasters.apiary-mock.com/questions";
final JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
frags.clear();
try {
for(int i = 0; i < response.length(); i++) {
JSONObject jrResponse = response.getJSONObject(i);
String question = jrResponse.getString("question");
abc = new String[question.length()];
JSONArray choiceArray = jrResponse.getJSONArray("choices");
// TODO: parse the JSON to get arguments
Frag f = new Frag();
f.setArguments(...); // set the arguments
frags.add(f); // store for the adapter
} catch (JSONException e) {
e.printStackTrace();
}
// Create a PagerAdapter here using list of Fragments
// set adapter to viewpager here
} // end of onResponse
Then, for example, getItem, you would return frags.get(position)
I am trying to feed my custom GridView with data fetched from Facebook Graph API. This data is a list of Album objects containing the picture for the album of the current user and the name of the album.
Fetching data doesn't represent a problem since I can see it in the LOGCAT.
What seems to be a problem is my GridView Adapter I suppose, the program doesn't give any particular error and this makes me confused.
Note that the MainActivity which will not be displayed here serves only to connect a user via Facebook account (there is no problem in this Activity)
Here is my different classes :
----LoggedInActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.AccessToken;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.login.LoginManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class LoggedInActivity extends Activity {
String name, surname, ID;
TextView nameOfUser;
Button logout;
GridView gridView;
GridViewAdapter gridViewAdapter;
List<Album> albumList = new ArrayList<Album>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle inBundle = getIntent().getExtras();
name = inBundle.getString("name");
surname = inBundle.getString("surname");
ID = inBundle.getString("ID");
setContentView(R.layout.activity_logged_in);
nameOfUser = (TextView) findViewById(R.id.name);
nameOfUser.setText(name + " " + surname);
logout = (Button) findViewById(R.id.logout);
gridView = (GridView) findViewById(R.id.myGridView);
albumList = getAlbums();
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LoginManager.getInstance().logOut();
Intent login = new Intent(LoggedInActivity.this, MainActivity.class);
startActivity(login);
finish();
}
});
gridViewAdapter = new GridViewAdapter(getBaseContext(), albumList);
gridView.setAdapter(gridViewAdapter);
}
public List<Album> getAlbums() {
albumList = new ArrayList<Album>();
GraphRequest request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/me/albums",
new GraphRequest.Callback() {
Album album = null;
#Override
public void onCompleted(GraphResponse response) {
JSONObject jsonDATA = response.getJSONObject();
JSONArray data = jsonDATA.optJSONArray("data");
for(int i = 0 ; i< data.length(); i++){
try {
JSONObject e = data.getJSONObject(i);
String name = e.optString("name");
JSONObject picture = e.getJSONObject("picture");
JSONObject dataOfPicture = picture.getJSONObject("data");
String url = dataOfPicture.optString("url");
album = new Album(name, url);
albumList.add(album);
Log.d("Mine",name + url);
} catch (JSONException e1) {
Toast.makeText(getBaseContext(), "Problem with JSON parsing", Toast.LENGTH_SHORT).show();
}
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "picture,name");
request.setParameters(parameters);
request.executeAsync();
return albumList;
}
}
------Album.java
public class Album {
public String album_name;
public String album_image;
public Album(String album_name, String album_image) {
this.album_name = album_name;
this.album_image = album_image;
}
public String getAlbum_name() {
return album_name;
}
public String getAlbum_image() {
return album_image;
}
public void setAlbum_name(String album_name) {
this.album_name = album_name;
}
public void setAlbum_image(String album_image) {
this.album_image = album_image;
}
}
-----GridViewAdapter.java
import android.content.Context;
import android.graphics.BitmapFactory;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.net.URL;
import java.util.List;
public class GridViewAdapter extends BaseAdapter {
private List<Album> albumList;
private Context context;
public GridViewAdapter(#NonNull Context context, #NonNull List<Album> objects) {
this.albumList = objects;
this.context = context;
}
#Override
public int getCount() {
return albumList.size();
}
#Nullable
#Override
public Album getItem(int position) {
return albumList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View v = convertView;
if(v==null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.item,null);
}
Album album = getItem(position);
ImageView imageView = (ImageView)v.findViewById(R.id.imageHolder);
TextView description = (TextView)v.findViewById(R.id.albumDesc);
try {
imageView.setImageBitmap(BitmapFactory.decodeStream((new URL(album.getAlbum_image())).openConnection().getInputStream()));
} catch (IOException e) {
Toast.makeText(context, "Problem with input output streams", Toast.LENGTH_SHORT).show();
}
description.setText(album.getAlbum_name());
return v;
}
}
------item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageHolder"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="#drawable/com_facebook_profile_picture_blank_square" />
<TextView
android:layout_width="wrap_content"
android:text="photo"
android:textSize="15sp"
android:id="#+id/albumDesc"
android:layout_below="#+id/imageHolder"
android:layout_marginLeft="20dp"
android:layout_height="wrap_content" />
</RelativeLayout>
------Activity_logged_in.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ichou.facebooktest.LoggedInActivity">
<LinearLayout
android:id="#+id/intro"
android:layout_width="368dp"
android:layout_height="40dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:orientation="horizontal">
<TextView
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_marginTop="0dp"
android:paddingTop="10dp"
android:text="username"
android:id="#+id/name"/>
<Button
android:layout_width="70dp"
android:layout_height="35dp"
android:text="logout"
android:id="#+id/logout"/>
</LinearLayout>
<GridView
android:layout_below="#+id/intro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myGridView"
android:layout_marginTop="10dp"
android:paddingTop="2dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:numColumns="2"
android:columnWidth="150dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
/>
</RelativeLayout>
write your code like in adapter below...
you do wrong line in inflate layout in getView() method
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View v = convertView;
if(v==null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.item,convertView, false);
}
Album album = getItem(position);
ImageView imageView = (ImageView)v.findViewById(R.id.imageHolder);
TextView description = (TextView)v.findViewById(R.id.albumDesc);
try {
imageView.setImageBitmap(BitmapFactory.decodeStream((new URL(album.getAlbum_image())).openConnection().getInputStream()));
} catch (IOException e) {
Toast.makeText(context, "Problem with input output streams", Toast.LENGTH_SHORT).show();
}
description.setText(album.getAlbum_name());
return v;
}
I've been struggling to get a listview to display correctly.
To clarify, I need a scrollview above the listview which is why I haven't extended a listfragment.
I need title and description to be separate elements. I can see how I have put them into a class so I think I'm half way there. If someone could help me out that would be great.
PhotosFragment.java
package info.androidhive.slidingmenu;
import android.app.Fragment;
import android.app.ListFragment;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PhotosFragment extends Fragment {
ListView list;
TextView pm;
TextView sp;
ArrayList<HashMap<String, String>> mlist = new ArrayList<HashMap<String,String>>();
private static final String TAG_APPLE = "Apple";
private static final String TAG_PHONEMODEL = "PhoneModel";
private static final String TAG_SPECS = "specs";
JSONArray model = null;
public PhotosFragment(){}
ListView mListView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_photos, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
mListView = (ListView) getView().findViewById(R.id.mListView);
new RequestTask().execute("http://www.horwichadvertiser.co.uk/app/index.php?Type=8&catid=7&userid=4");
}
private static final String TAG = MainActivity.class.getSimpleName();
JSONObject obj;
JSONArray stories;
public class RequestTask extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pm = (TextView)getView().findViewById(R.id.phonemodel);
sp = (TextView)getView().findViewById(R.id.specification);
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
//Log.d(TAG, responseString);
} else {
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
// Log.d(TAG, String.valueOf(e));
} catch (IOException e) {
//TODO Handle problems..
// Log.d(TAG, String.valueOf(e));
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
super.onPostExecute(result);
//Log.e(TAG, result);
try {
obj = new JSONObject(result);
stories = obj.getJSONArray("stories");
// initialize the items list
List<ListViewItem> mItems = new ArrayList<ListViewItem>();
for (int i = 0; i < stories.length(); i++) {
JSONObject storyObj = stories.getJSONObject(i);
if (!storyObj.has("Advert")) {
newsStories newsStories = new newsStories();
newsStories.setTitle(storyObj.getString("subject"));
newsStories.setBody(storyObj.getString("body"));
mItems.add(new ListViewItem(newsStories.getTitle(), newsStories.getBody(), ""));
}
else {
newsStories newsStories = new newsStories();
newsStories.setThumbnailUrl(storyObj.getString("Advert"));
mItems.add(new ListViewItem("", "", newsStories.getThumbnailUrl()));
}
}
ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<ListViewItem>(getActivity(), android.R.layout.simple_list_item_1, mItems);
mListView.setTextFilterEnabled(true);
// ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<ListViewItem>(getActivity(), android.R.layout.two_line_list_item, mItems);
//mListView.setAdapter(adapter);
mListView.setAdapter(adapter);
}
catch (JSONException e) {
e.printStackTrace();
}
}
public class newsStories {
private String name, thumbnailUrl, body;
public String getTitle() {
return name;
}
public void setTitle(String name) {
this.name = name;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body.substring(0, 150);
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
//Check if thumbnail exists, if so take out spaces and replace with -
this.thumbnailUrl = thumbnailUrl;
}
}
}
public class ListViewItem{
public final String title; // the text for the ListView item title
public final String description; // the text for the ListView item description
public final String adUrl;
//public final Drawable image;
public ListViewItem(String title, String description, String Advert_Url) {
if (Advert_Url != null && !Advert_Url.isEmpty()) {
String Advert = "http://www.horwichadvertiser.co.uk/images/horwichadvertiserlogo.png?width=700&height=200";
this.title = "";
this.description = "";
this.adUrl = Advert;
} else {
this.title = title;
this.description = description;
this.adUrl = "";
}
}
#Override
public String toString() {
return this.title + ".\r\n" + Html.fromHtml(this.description);
}
}
}
Fragment_Photos.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="150dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button4" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button5" />
</LinearLayout>
</HorizontalScrollView>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="50dp"
android:id="#+id/relativeLayout">
<TextView
android:id="#+id/body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="22px" />
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="13px" />
</RelativeLayout>
<ListView
android:id="#id/mListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="#+id/relativeLayout">
</ListView>
</RelativeLayout>
Your resource xml is incorrect.
1.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
android:orientation is used with LinearLayout, not RelativeLayout
2.
<ListView
android:id="#id/mListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="#+id/relativeLayout">
</ListView>
Incorrect use of android:layout_below - value should be an existing id: "#id/relativeLayout" (without + after #).
android:id="#id/mListView" incorrectly assigned id. If it is a new ID, then should be android:id="#+id/mListView"
Probably you'd like to use LinearLayouts instead of relative
fill_parent is obsolete until you develop for some API 7. Should be match_parent instead