I'm trying to make an app which has so many recyclerview, cardview init and all of them are in one activity. So, there are a lot of lists and these lists has horizontal orientation. I'm fetching data from JSON file and showing them on these lists. I know there is a long way to do it. But i believe there is more effective way to do it also. I'm not an expert. But i don't want to write so many different recyclerview, layoutmanager and adapter. So can you teach me how to do this?
Here is my codes;
Games.class;
public class Games extends AppCompatActivity {
RecyclerView recyclerView, recyclerView2;
ArrayList<ModelGames> modelGames;
private RequestQueue mQueue;
GamesAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_games);
modelGames = new ArrayList<>();
recyclerView = findViewById(R.id.gamesPageRecyclerView);
recyclerView2 = findViewById(R.id.gamesPageRecyclerView2);
mQueue = Volley.newRequestQueue(this);
releasedOn19();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView.LayoutManager gamesLiLayoutManager = linearLayoutManager;
recyclerView.setLayoutManager(gamesLiLayoutManager);
adapter = new GamesAdapter(this, modelGames);
recyclerView.setAdapter(adapter);
}
private void releasedOn19() {
String popularIn2019 = "https://api.rawg.io/api/games?dates=2019-01-01,2019-12-31&ordering=-added";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, popularIn2019, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++){
JSONObject result = jsonArray.getJSONObject(i);
String gameName = result.getString("name");
String gameImage = result.getString("background_image");
modelGames.add(new ModelGames(gameName, gameImage));
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mQueue.add(request);
}
}
ModelGames;
public class ModelGames {
private String text, image;
public ModelGames(String text, String image) {
this.text = text;
this.image = image;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
GamesAdapter;
public class GamesAdapter extends RecyclerView.Adapter<GamesAdapter.ViewHolder> {
private Context mContext;
private ArrayList<ModelGames> mList;
GamesAdapter(Context context, ArrayList<ModelGames> list){
mContext = context;
mList = list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.rv_game_items, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
ModelGames getItem = mList.get(position);
TextView gameName = holder.game_title;
ImageView gameImage = holder.game_image;
Glide.with(mContext).asBitmap().load(getItem.getImage()).into(gameImage);
gameName.setText(mList.get(position).getText());
}
#Override
public int getItemCount() {
return mList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView game_image;
TextView game_title;
public ViewHolder(#NonNull View itemView) {
super(itemView);
game_image = itemView.findViewById(R.id.cardviewImage);
game_title = itemView.findViewById(R.id.cardviewText);
}
}
}
And here is my activity_games.xml. I added second recyclerview. But i didn't use that in anywhere
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="165dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="2019 Yılında Çıkan Oyunlar"
android:textStyle="bold"
android:textSize="18sp"
android:gravity="center_horizontal|center_vertical"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/gamesPageRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="165dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="2018 Yılında Çıkan Oyunlar"
android:textStyle="bold"
android:textSize="18sp"
android:gravity="center_horizontal|center_vertical"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/gamesPageRecyclerView2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
Related
I know there is other questions like this with answers but they don't help me...
So I have a Fragment, in this one I use Volley to get a JSON from a Web API. What I want to do is to "refresh" my recycler view with the data I get in my response.
I have tried to add a method in my adapter. But nothing append when I try to change my adapter in my Volley.onresponse() method.
There is my Fragment :
public class TicketsIncidentsFragment extends Fragment implements Response.ErrorListener, Response.Listener<String> {
RequestQueue queue;
StringRequest stringRequest;
ListView listView;
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
String url;
private TicketsIncidentsViewModel ticketsIncidentsViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
ticketsIncidentsViewModel =
ViewModelProviders.of(this).get(TicketsIncidentsViewModel.class);
View root = inflater.inflate(R.layout.fragment_ticketsincidents, container, false);
return root;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
RecyclerView recyclerView = (RecyclerView)getView().findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager= new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
MyAdapterTI myAdapterTI=new MyAdapterTI();
recyclerView.setAdapter(myAdapterTI);
queue = Volley.newRequestQueue(getActivity().getApplicationContext());
url = "http://myip/select/ticketsI";
stringRequest = new StringRequest(GET, url, TicketsIncidentsFragment.this, TicketsIncidentsFragment.this);
queue.add(stringRequest);
}
#Override
public void onErrorResponse(VolleyError error) {
}
#Override
public void onResponse(String response) {
RecyclerView recyclerView = (RecyclerView)getView().findViewById(R.id.recyclerview);
Gson gsonTicketsIncidents = new Gson();
ResponseJson responseJson = new ResponseJson();
responseJson = (ResponseJson) gsonTicketsIncidents.fromJson(response, ResponseJson.class);
List<Object> listTicketsIncidents = responseJson.getResponse();
try {
JSONArray tis = new JSONArray(listTicketsIncidents.toArray());
ArrayList<String> date = new ArrayList<String>();
ArrayList<String> nomUser = new ArrayList<String>();
for (int i = 0 ; i< tis.length(); i++) {
JSONObject ticketIncident = tis.getJSONObject(i);
nomUser.add(ticketIncident.get("NOMUSER").toString());
date.add(ticketIncident.get("DateSAISIE").toString());
}
MyAdapterTI myAdapterTI=new MyAdapterTI();
myAdapterTI.getList(nomUser, date);
recyclerView.setAdapter(myAdapterTI);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
There is my adapter :
public class MyAdapterTI extends RecyclerView.Adapter<MyAdapterTI.MyViewHolder> {
private List<Pair<String, String>> TI;
public void getList(ArrayList<String> nomUser, ArrayList<String> date){
for(int i =0; i<nomUser.size();i++){
TI = Arrays.asList( Pair.create(nomUser.get(i), date.get(i)));
}
}
#NonNull
#Override
public MyAdapterTI.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.list_cell_ti, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyAdapterTI.MyViewHolder holder, int position) {
Pair<String, String> pair = TI.get(position);
holder.display(pair);
}
#Override
public int getItemCount() {
return 0;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
private TextView nomUser;
private TextView date;
private Pair<String, String> currentPair;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
nomUser=(TextView)itemView.findViewById(R.id.nomuser);
date=(TextView)itemView.findViewById(R.id.date);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
}
});
}
public void display(Pair<String, String> pair) {
currentPair=pair;
nomUser.setText(pair.first);
date.setText(pair.second);
}
}
}
And there is the layout :
<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="match_parent">
<ListView
android:id="#+id/listview_TI"
android:layout_width="97dp"
android:layout_height="34dp"
android:layout_marginTop="24dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.917"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="409dp"
android:layout_height="680dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.039" />
</androidx.constraintlayout.widget.ConstraintLayout>
Thank's for you're help
UPDATE :
Now my MyAdapter.getList() looks like this :
public void getList(ArrayList<String> nomUser, ArrayList<String> date){
for(int i =1; i<nomUser.size();i++){
TI.add(Pair.create(nomUser.get(i), date.get(i)));
}
notifyDataSetChanged();
}
But nothing change yet.
Last UPDATE :
The problem has been solved.
It's a ridiculous mistake I've made in my Adapter.
I used to return 0 but the solution is this :
#Override
public int getItemCount() {
return TI.size();
}
just change
#Override
public int getItemCount() {
return 0;
}
to
#Override
public int getItemCount() {
if(TI == null)
return 0;
else
return TI.size;
}
private List<Pair<String, String>> TI = new ArrayList();
public void getList(ArrayList<String> nomUser, ArrayList<String> date){
for(int i =0; i<nomUser.size();i++){
TI.add(Pair.create(nomUser.get(i), date.get(i)));
}
notifyDataSetChanged();
}
layoutManager= new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
MyAdapterTI myAdapterTI=new MyAdapterTI(getActivity().getApplicationContext(),ThisIsYourList);
recyclerView.setAdapter(myAdapterTI);
Don't do this in response
MyAdapterTI myAdapterTI=new MyAdapterTI();
recyclerView.setAdapter(myAdapterTI);
myAdapterTI make this global variable
Only update your list and then
myAdapterTI.notifyDataSetChanged();
Or in your adapter, you can do
this.notifyDataSetChanged(); ////in getList
I have news app, which is provide news post from json url and I want to add refresh swipe to get news post. When I refresh the layout, how I can add it to my MainActivity and this my class here below:
public class MainActivity extends AppCompatActivity implements ExampleAdapter.OnItemClickListener {
public static final String EXTRA_URL = "imageUrl";
public static final String EXTRA_CREATOR = "creatorName";
private RecyclerView mRecyclerView;
private ExampleAdapter mExampleAdapter;
private ArrayList<ExampleItem> mExampleList;
private RequestQueue mRequestQueue;
String API_KEY = "850e0efe6adf4eb38afefa14d33e4b48"; // ### YOUE NEWS API HERE ###
String NEWS_SOURCE = "bbc-news";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mExampleList = new ArrayList<>();
mRequestQueue = Volley.newRequestQueue(this);
parseJSON();
}
private void parseJSON() {
String url = "http://newsapi.org/v1/articles?source="+NEWS_SOURCE+"&sortBy=top&apiKey="+API_KEY;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.optJSONArray("articles");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
String creatorName = hit.getString("title");
String imageUrl = hit.getString("urlToImage");
mExampleList.add(new ExampleItem(imageUrl, creatorName));
}
mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
mExampleAdapter.setOnItemClickListener(MainActivity.this);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
#Override
public void onItemClick(int position) {
Intent detailIntent = new Intent(this, DetailActivity.class);
ExampleItem clickedItem = mExampleList.get(position);
detailIntent.putExtra(EXTRA_URL, clickedItem.getImageUrl());
detailIntent.putExtra(EXTRA_CREATOR, clickedItem.getCreator());
startActivity(detailIntent);
}
}
Exampleadapter.java
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
private Context mContext;
private ArrayList<ExampleItem> mExampleList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public ExampleAdapter(Context context, ArrayList<ExampleItem> exampleList) {
mContext = context;
mExampleList = exampleList;
}
#Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.example_item, parent, false);
return new ExampleViewHolder(v);
}
#Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
ExampleItem currentItem = mExampleList.get(position);
String imageUrl = currentItem.getImageUrl();
String creatorName = currentItem.getCreator();
holder.mTextViewCreator.setText(creatorName);
Picasso.with(mContext).load(imageUrl).fit().centerInside().into(holder.mImageView);
}
#Override
public int getItemCount() {
return mExampleList.size();
}
public class ExampleViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextViewCreator;
public TextView mTextViewLikes;
public ExampleViewHolder(View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.image_view);
mTextViewCreator = itemView.findViewById(R.id.text_view_creator);
mTextViewLikes = itemView.findViewById(R.id.text_view_likes);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
});
}
}
}
Exampleitem.java
public class ExampleItem {
private String mImageUrl;
private String mCreator;
public ExampleItem(String imageUrl, String creator) {
mImageUrl = imageUrl;
mCreator = creator;
}
public String getImageUrl() {
return mImageUrl;
}
public String getCreator() {
return mCreator;
}
}
activity_main.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="recylerviewjsonexample.codinginflow.com
.recylerviewjsonexample.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray" />
exmple_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 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:layout_margin="8dp"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<ImageView
android:id="#+id/image_view"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/text_view_creator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Creator Name"
android:textColor="#android:color/black"
android:textSize="20sp" />
<TextView
android:id="#+id/text_view_likes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Like: " />
</LinearLayout>
</android.support.v7.widget.CardView>
Inside your XML file
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
In your java class you will clear your old list and than call your API method again
binding.refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
if (data_list != null) {
data_list.clear();
}
CallyourMethod();
binding.refreshLayout.setRefreshing(false);
}
});
You can place a SwipeRefreshLayout around your RecyclerView as:
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray" />
</android.support.v4.widget.SwipeRefreshLayout>
Inside your onCreateMethod() of MainActivity.java add
swipeRefreshLayout.setEnabled(true);
To show a loader when the list is swiped to refresh you can add:
swipeRefreshLayout.setProgressViewEndTarget(true, SWIPE_REFRESH_LAYOUT_OFFSET);
SwipeRefreshLayout provides the callback when the list is swiped to perform necessary action
swipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
//perform your action here
}
});
I spent a lot of time debugging this code but unfortunately could not find the bug, can someone help me find the issue in this code. I am not able to see data on the activity page. Although I have found the I am getting response data from the server.
Activity Class
public class SelectServiceActivity extends AppCompatActivity {
private TextView textView;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_service);
recyclerView = (RecyclerView) findViewById(R.id.select_service_rv);
String serviceTypeId = getIntent().getStringExtra(AppConstants.SELECTED_SERVICE_TYPE_ID);
getProductDetailsByProductId(serviceTypeId);
}
private void getProductDetailsByProductId(String serviceTypeId) {
final List<SelectServiceBean> selectServiceList = new ArrayList<>();
final JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Request.Method.GET,
APIEndpoints.SERVICE_LIST_URI + serviceTypeId,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
if (response.length() > 0) {
for (int i = 0; i < response.length(); i++) {
try {
selectServiceList.add(DatabaseObjectsMapper.selectServiceBeanMapper((JSONObject) response.get(i)));
} catch (JSONException e) {
Toast.makeText(SelectServiceActivity.this, "Something went wrong : " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
recyclerView.setAdapter(new SelectServiceAdapter(getApplicationContext(),selectServiceList));
} else {
Toast.makeText(SelectServiceActivity.this, "No Response From Server!", Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(SelectServiceActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
});
VolleySingleton.getInstance(SelectServiceActivity.this).addToRequestQueue(jsonArrayRequest);
}
}
Adapter Class
public class SelectServiceAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<SelectServiceBean> selectServiceList;
public SelectServiceAdapter(final Context context, final List<SelectServiceBean> selectServiceList) {
this.context = context;
this.selectServiceList = selectServiceList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View row = LayoutInflater.from(context).inflate(R.layout.item_select_service, parent, false);
return (new Item(row));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((Item) holder).serviceTypeIssue.setText(selectServiceList.get(position).getServiceTypeIssue());
((Item) holder).serviceTypeIssue.setText(selectServiceList.get(position).getServiceType());
}
#Override
public int getItemCount() {
return selectServiceList.size();
}
public static class Item extends RecyclerView.ViewHolder {
private TextView serviceTypeIssue;
private TextView serviceType;
public Item(View view) {
super(view);
serviceTypeIssue = view.findViewById(R.id.service_type_issue);
}
}
}
Single View Item
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatTextView
android:id="#+id/service_type_issue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Sample text" />
<android.support.v7.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1sp"
android:background="#color/lightGrey" />
</LinearLayout>
Recyclerview File
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/select_service_rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
From docs
A LayoutManager must be provided for RecyclerView to function.
You need to add the layoutManager
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_service);
recyclerView = (RecyclerView) findViewById(R.id.select_service_rv);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
//^^^^^^^^^^^
recyclerView.setLayoutManager(mLayoutManager);
//^^^^^^^^^^^^^^^^^^^^
String serviceTypeId = getIntent().getStringExtra(AppConstants.SELECTED_SERVICE_TYPE_ID);
getProductDetailsByProductId(serviceTypeId);
}
Improvement :
Initialize serviceType in Item class and use it in onBindViewHolder
public Item(View view) {
super(view);
serviceTypeIssue = view.findViewById(R.id.service_type_issue);
serviceType = view.findViewById(R.id.yourID);
//^^^^^^^
}
Keep a reference to new SelectServiceAdapter so that later you can use notify functions for more optimal performance
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((Item)holder).serviceTypeIssue.setText(selectServiceList.get(position).getServiceTypeIssue());
((Item)holder).serviceType.setText(String.valueOf(selectServiceList.get(position).getServiceType()));
//^^^^^^^^
}
I got an error in recycler view using fragment. I have read stackoverflow answers but it not solve. PLease help me.
Recycler reference tutorial
http://www.android-examples.com/android-recyclerview-listview-with-imageview-textview-json/
When i use in without fragment it work as fine but in fragment it shows error.
My codes shown below.
FriendsFragment.java
public class FriendsFragment extends android.support.v4.app.Fragment {
List<GetDataAdapter> GetDataAdapter1;
RecyclerView recyclerView;
RecyclerView.LayoutManager recyclerViewlayoutManager;
RecyclerView.Adapter recyclerViewadapter;
String GET_JSON_DATA_HTTP_URL = "http://192.168.43.7/work/ecom/2/1.php";
String JSON_IMAGE_TITLE_NAME = "image_title";
String JSON_IMAGE_URL = "image_url";
JsonArrayRequest jsonArrayRequest ;
RequestQueue requestQueue ;
public FriendsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_friends, container, false);
GetDataAdapter1 = new ArrayList<>();
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview1);
recyclerView.setHasFixedSize(true);
recyclerViewlayoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(recyclerViewlayoutManager);
JSON_DATA_WEB_CALL();
// Inflate the layout for this fragment
return rootView;
}
public void JSON_DATA_WEB_CALL(){
jsonArrayRequest = new JsonArrayRequest(GET_JSON_DATA_HTTP_URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d("LOGTAG", "Response :"+response);
JSON_PARSE_DATA_AFTER_WEBCALL(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(jsonArrayRequest);
}
public void JSON_PARSE_DATA_AFTER_WEBCALL(JSONArray array){
for(int i = 0; i<array.length(); i++) {
GetDataAdapter GetDataAdapter2 = new GetDataAdapter();
JSONObject json = null;
try {
json = array.getJSONObject(i);
GetDataAdapter2.setImageTitleNamee(json.getString(JSON_IMAGE_TITLE_NAME));
GetDataAdapter2.setImageServerUrl(json.getString(JSON_IMAGE_URL));
} catch (JSONException e) {
e.printStackTrace();
}
GetDataAdapter1.add(GetDataAdapter2);
}
recyclerViewadapter = new RecyclerViewAdapter(GetDataAdapter1, getContext());
recyclerView.setAdapter(recyclerViewadapter);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
Context context;
List<GetDataAdapter> getDataAdapter;
ImageLoader imageLoader1;
public RecyclerViewAdapter(List<GetDataAdapter> getDataAdapter, Context context){
super();
this.getDataAdapter = getDataAdapter;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_items, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder Viewholder, int position) {
GetDataAdapter getDataAdapter1 = getDataAdapter.get(position);
imageLoader1 = ServerImageParseAdapter.getInstance(context).getImageLoader();
imageLoader1.get(getDataAdapter1.getImageServerUrl(),
ImageLoader.getImageListener(
Viewholder.networkImageView,//Server Image
R.mipmap.ic_launcher,//Before loading server image the default showing image.
android.R.drawable.ic_dialog_alert //Error image if requested image dose not found on server.
)
);
Viewholder.networkImageView.setImageUrl(getDataAdapter1.getImageServerUrl(), imageLoader1);
Viewholder.ImageTitleNameView.setText(getDataAdapter1.getImageTitleName());
}
#Override
public int getItemCount() {
return getDataAdapter.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView ImageTitleNameView;
public NetworkImageView networkImageView ;
public ViewHolder(View itemView) {
super(itemView);
ImageTitleNameView = (TextView) itemView.findViewById(R.id.textView_item) ;
networkImageView = (NetworkImageView) itemView.findViewById(R.id.VollyNetworkImageView1) ;
}
}
}
fragment_friends.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.ecom.fragment2.FriendsFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
recyclerview_items.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardview1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="3dp"
card_view:contentPadding="3dp"
card_view:cardCornerRadius="3dp"
card_view:cardMaxElevation="3dp"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/VollyNetworkImageView1"
android:layout_width="150dp"
android:layout_height="100dp"
android:src="#mipmap/ic_launcher"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Image Name"
android:id="#+id/textView_item"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/VollyNetworkImageView1"
android:layout_toEndOf="#+id/VollyNetworkImageView1"
android:layout_marginLeft="20dp"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
You should make your custom linearlayout manager. Sometimes there is a scenario: If you scroll fast then there causes Exception in you recycleView. To avoid this problem you have to implement your custom layout manager like below:
public class CustomLinearLayoutManager extends LinearLayoutManager {
private Context mContext;
public CustomLinearLayoutManager(Context context, int orientation,boolean reverseLayout){
super(context, orientation, reverseLayout);
mContext=context;
}
#Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (Exception e) {
Constants.errorLog("onLayoutChildren :" , e.toString());
}
}
}
Now use this layout manager in your recycleview like this:
LinearLayoutManager recyclerViewlayoutManager = new CustomLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(recyclerViewlayoutManager );
Hope you will now avoid the exception i mentioned.
The problem is adding permission in manifest file.
Add
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
It work as fine.
I have a recyclerview which populates data from SQL database. Now each row in the recyclerview has a seekbar which when moved displays it's progress in a textview inside the same row. The problem is when I scroll the recyclerview up or down then return back to the first changed row, the seekbar is returned to its default position. How can I make it save the new position ? In normal activities/fragments I use lifecycle methods as "onPause" to save/restore the state. Here we have onAttachedToRecyclerView, I think it should solve my problem but I don't know exactly how.
EDIT : here is a full simple app files which I'm working on to test this problem.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private List<Score> scoreList = new ArrayList<>();
private RecyclerView recyclerView;
private MyAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mAdapter = new MyAdapter(scoreList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
prepareScoreData();
}
private void prepareScoreData() {
Score score = new Score("title", 5);
scoreList.add(score);
for(int i= 0; i<1000; i++){
score = new Score("title", 5);
scoreList.add(score);
}
mAdapter.notifyDataSetChanged();
}
}
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Score> scoresList;
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView title, scoreView;
SeekBar seekbar;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
scoreView = (TextView) view.findViewById(R.id.score);
seekbar = (SeekBar) view.findViewById(R.id.seekbar);
}
}
public MyAdapter(List<Score> scoresList) {
this.scoresList = scoresList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final Score score = scoresList.get(position);
holder.title.setText(score.getTitle());
if (!score.getProgressed()) {
holder.seekbar.setProgress(0) ;
} else {
holder.seekbar.setProgress(score.getSeekbarProgress());
}
holder.seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
holder.scoreView.setText(String.valueOf(i));
score.setSeekbarProgress(i);
score.setProgressed(true);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
#Override
public int getItemCount() {
return scoresList.size();
}
}
Score class
public class Score {
private String title;
int seekbarProgress;
boolean progressed;
public Score() {
}
public Score(String title,int seekbarProgress) {
this.title = title;
this.seekbarProgress = seekbarProgress;
}
public void setProgressed(boolean progressed) {
this.progressed = progressed;
}
public void setTitle(String title) {
this.title = title;
}
public void setSeekbarProgress(int seekbarProgress) {
this.seekbarProgress = seekbarProgress;
}
public String getTitle() {
return title;
}
public int getSeekbarProgress() {
return seekbarProgress;
}
public boolean getProgressed() {
return progressed;
}
}
MainActivity_Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.moaness.tut_recyclerview.MainActivity">
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="60dp"
android:paddingBottom="60dp"
android:layout_marginBottom="10dp"
android:clickable="true"
android:background="#f2f2f2"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:text="title"
android:textColor="#color/title"
android:textSize="16dp"
android:paddingTop="16dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/score"
android:text="score"
android:layout_below="#+id/title"
android:textSize="16dp"
android:paddingBottom="16dp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/score"
android:id="#+id/seekbar"
/>
</RelativeLayout>
If you are using recyclerview you need to maintain states of each row, means if you are checking using a condition(i.e. if) at any stage of recyclerview item(in recyclerview adapter class) then you need to handle else as well. I can send you a code snippet so you can have a good idea for recyclerview adapter.
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ViewHolder> {
List<ViewHolder> holders = new ArrayList<ViewHolder>();
private ArrayList<ContactModel> arrayList = new ArrayList<>();
private Context context;
private LayoutInflater inflater;
public void clearAdapter() {
arrayList.clear();
notifyDataSetChanged();
}
public ContactsAdapter(Context context, ArrayList<ContactModel> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
public void setList(ArrayList<ContactModel> listSearch) {
this.arrayList = listSearch;
notifyItemRangeChanged(0, listSearch.size());
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.custom_row_for_contacts, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
holders.add(viewHolder);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final ContactModel current = this.arrayList.get(position);
holder.txtDriverName.setText(current.getName());
holder.txtDriverPhone.setText(current.getPhone());
if (current.getImgUrl().length() > 0) {
String urlLicenceThumb = UrlEndPoints.parentUrl + current.getImgUrl();
Glide.with(context).load(urlLicenceThumb).error(R.mipmap.ic_launcher).into(holder.imgDriver);
} else {
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imgDriver);
}
}
public void delete(int position) {
arrayList.remove(position);
notifyItemRemoved(position);
}
#Override
public int getItemCount() {
return (null != arrayList ? arrayList.size() : 0);
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView txtDriverName, txtDriverPhone;
private CircleImageView imgDriver;
private Button btnInvite;
private CheckBox chkAdd;
public ViewHolder(View itemView) {
super(itemView);
chkAdd = (CheckBox) itemView.findViewById(R.id.chkAdd);
imgDriver = (CircleImageView) itemView.findViewById(R.id.imgDriver);
txtDriverName = (TextView)itemView.findViewById(R.id.txtDriverName);
txtDriverPhone = (TextView) itemView.findViewById(R.id.txtDriverPhone);
btnInvite = (Button) itemView.findViewById(R.id.btnInvite);
}
}
}