I have created RecyclerView and showing data from JSON.
Issue I'm facing is, while Toast data is showing correctly, but in RecyclerView same data is not appear.
Here is code:
public class MainActivity extends AppCompatActivity {
private static final int NUM_LIST_ITEMS = 100;
private static final String TOKEN =
"71cf2d3dec294394e267fbb0bf28916f4198f8d6";
private CuloAdapter culoAdapter;
List<Hotel> lh = new ArrayList<>();
RecyclerView recyclerView;
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rv_tiketapi);
LinearLayoutManager layout = new LinearLayoutManager(this);
layout.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layout);
CuloAdapter ar = new CuloAdapter(lh);
recyclerView.setAdapter(ar);
loadHotelLocation();
}
private void loadHotelLocation() {
final search apiService = ApiService.getService(search.class);
retrofit2.Call<SingleResult<Hotel>> call = apiService.findHotel(TOKEN,
"json");
call.enqueue(new Callback<SingleResult<Hotel>>() {
#Override
public void onResponse(retrofit2.Call<SingleResult<Hotel>> call,
Response<SingleResult<Hotel>> response) {
if (response.body().getDiagnostic().isSuccess()) {
//SingleResult.ResultList list =
response.body().getResults();
List<Hotel> mHotels = (List<Hotel>)
response.body().getResults().getResult();
lh.addAll(mHotels);
Toast.makeText(getApplicationContext(), "OK" +lh,
Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(retrofit2.Call<SingleResult<Hotel>> call,
Throwable t) {
}
});
}
RecyclerView Adapter :
public class CuloAdapter extends
RecyclerView.Adapter<CuloAdapter.ViewHolder> {
public CuloAdapter(List<Hotel> lh) {
this.items = lh;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtTitle;
public TextView txtSubTitle;
public ImageView imgIcon;
public ViewHolder(final View container) {
super(container);
txtTitle = (TextView) container.findViewById(R.id.airportName);
txtSubTitle = (TextView) container.findViewById(R.id.airportCode);
}
}
private List<Hotel> items;
public CuloAdapter(final Activity activity, List<Hotel> items) {
this.items = items;
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public void onBindViewHolder(CuloAdapter.ViewHolder holder, int position) {
Hotel item = items.get(position);
holder.txtTitle.setText(item.getLabel());
holder.txtSubTitle.setText(item.getId());
}
#Override
public CuloAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_flight, parent, false);
return new ViewHolder(v);
}
}
MainActivity 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="com.example.admin.exampletiketapi.MainActivity">
<EditText
android:id="#+id/et_find"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_tiketapi"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Item List XML :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/airportsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">
<TextView
android:id="#+id/airportName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="Soekarno Hatta" />
<TextView
android:id="#+id/airportCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="20" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:background="#DDD"
android:visibility="visible" />
</LinearLayout>
In your code you are trying to set adapter before loading data.
CuloAdapter ar = new CuloAdapter(lh);
recyclerView.setAdapter(ar);
loadHotelLocation();
What i found is You are getting data in loadHotelLocation(), but trying to set adpter before that,
Call notifyDatasetChanged after lh.addAll(mHotels). And check for null's else you are heading for crash in case search results are zero/null
Related
I am a new application developer. I use recycerview to display a set of images to the user.What I want to do now if the image is still not shown to the user, it shows in each image a circular effect.I sorry for that. This question may have been asked a lot time before now, but I could not find an answer to my question.
What I need to do like the following picture:
How I can do that ?
MyAdapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
List<List_Data>list_data;
Context ct;
public MyAdapter(List<List_Data> list_data, Context ct) {
this.list_data = list_data;
this.ct = ct;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_data,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final List_Data listData=list_data.get(position);
Picasso.with(ct)
.load(listData.getImageurl())
.into(holder.img);
}
#Override
public int getItemCount() {
return list_data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private ImageView img;
public ViewHolder(View itemView) {
super(itemView);
img=(ImageView)itemView.findViewById(R.id.image_view);
}
}
}
MainActivity
private static final String HI = "https://uniqueandrocode.000webhostapp.com/hiren/androidtutorial/androidweb.php";
private List<List_Data> list_data;
private MyAdapter adapter;
private RecyclerView rv;
private JsonArrayRequest request;
private RequestQueue requestQueue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv=(RecyclerView)findViewById(R.id.recycler_view);
rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(this));
list_data=new ArrayList<>();
getImageData();
}
private void getImageData() {
request=new JsonArrayRequest(HI, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSONObject jsonObject=null;
for (int i=0; i<response.length(); i++){
try {
jsonObject=response.getJSONObject(i);
List_Data listData=new List_Data(jsonObject.getString("imageurl"));
list_data.add(listData);
} catch (JSONException e) {
e.printStackTrace();
}
}
setupData(list_data);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue= Volley.newRequestQueue(this);
requestQueue.add(request);
}
private void setupData(List<List_Data> list_data) {
adapter=new MyAdapter(list_data,this);
rv.setAdapter(adapter);
}
}
<?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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
You are required to add a progress bar on the top of the RecylerView item layout.
<?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="match_parent">
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#tools:sample/avatars" />
<ProgressBar
android:id="#+id/progressBar2"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#+id/imageView3"
app:layout_constraintEnd_toEndOf="#+id/imageView3"
app:layout_constraintStart_toStartOf="#+id/imageView3"
app:layout_constraintTop_toTopOf="#+id/imageView3" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now inside your RecyclerViewAdapter's onBindViewHolder(ViewHolder holder, int position) method.
Add this code:
holder.progressBar.setVisibility(View.VISIBLE);
Change this code:
Picasso.with(ct)
.load(listData.getImageurl())
.into(holder.img);
To:
Picasso.with(ct)
.load(listData.getImageurl())
.into(holder.img, new Callback(){
#Override
public void onSuccess() {
holder.progressBar.setVisibility(View.GONE);
}
#Override
public void onError() {
holder.progressBar.setVisibility(View.GONE);
}
});
And also update your ViewHolder Too.
I tried the solutions on the other similar posts that I found here but they did not help me. I hope someone can help.
I get data from Unsplash's API and the ArrayList contains 10 items once I get a response, that's why I think It has to be something with the way the view is inflated.
This is code:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "unsplash";
private final String CLIENT_ID = "...myclientID...";
// testing keyword used on the API to search for pictures
private final String KEYWORD = "stackOverflow";
private final String urlBase = "https://api.unsplash.com/";
private Retrofit retrofit;
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
retrofit = new Retrofit.Builder()
.baseUrl(urlBase)
.addConverterFactory(GsonConverterFactory.create())
.build();
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
recyclerViewAdapter = new RecyclerViewAdapter();
recyclerView.setAdapter(recyclerViewAdapter);
getData();
}
private void getData() {
PictureService service = retrofit.create(PictureService.class);
Call<PictureResponse> pictureResponseCall = service.getPictureList(KEYWORD, CLIENT_ID);
pictureResponseCall.enqueue(new Callback<PictureResponse>() {
#Override
public void onResponse(Call<PictureResponse> call, Response<PictureResponse> response) {
if (response.isSuccessful()){
PictureResponse pictureResponse = response.body();
ArrayList<UnsplashPic> pictureList = pictureResponse.getResults();
recyclerViewAdapter.addPictures(pictureList);
}else{
Log.e (TAG, " onResponse " + response.errorBody());
}
}
#Override
public void onFailure(Call<PictureResponse> call, Throwable t) {
Log.e (TAG, " onFailure " + t.getMessage());
}
});
}
}
My adapter class:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private ArrayList<UnsplashPic> pictureList;
public RecyclerViewAdapter (){
pictureList = new ArrayList<>();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_view_holder, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
UnsplashPic pic = pictureList.get(i);
viewHolder.artistName.setText(pic.user.getUsername());
viewHolder.unsplash.setText("Unsplash");
}
#Override
public int getItemCount() {
return pictureList.size();
}
public void addPictures(ArrayList<UnsplashPic> pictureList) {
pictureList.addAll(pictureList);
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView artistName;
private TextView unsplash;
public ViewHolder (View itemView){
super(itemView);
imageView = itemView.findViewById(R.id.imageview);
artistName = itemView.findViewById(R.id.artist_name);
unsplash = itemView.findViewById(R.id.unsplash_name);
}
}
}
item_view_holder.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imageview"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#ababab"
android:contentDescription="unsplash picture" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Photo by "/>
<TextView
android:id="#+id/artist_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="on "/>
<TextView
android:id="#+id/unsplash_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true" />
</LinearLayout>
activity_main.xml
<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">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Search for pictures"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerview">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Here:
public void addPictures(ArrayList<UnsplashPic> pictureList) {
pictureList.addAll(pictureList);
notifyDataSetChanged();
}
you are actually adding the content of the pictureList you send as parameter of the function to that same list, your list from adapter is not updated.
You should do like this instead:
public void addPictures(ArrayList<UnsplashPic> pictureList) {
this.pictureList.addAll(pictureList);
notifyDataSetChanged();
}
I am using RecyclerView in Android with a model class that has title and details. Nothing is showing. Even after log inside Adapter nothing is shown in Android Monitor.
MainActivity.class
public ArrayList<Menu> menu_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
initUi();
}
public void initUi(){
RecyclerView menu_recycler = (RecyclerView) findViewById(R.id.main_menu_recycler_view);
//set the layout manager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation( linearLayoutManager.VERTICAL );
menu_recycler.setLayoutManager( linearLayoutManager );
//set adapter
MainMenuAdapter mainMenuAdapter = new MainMenuAdapter( getMenulist() );
menu_recycler.setAdapter( mainMenuAdapter );
}
public ArrayList<Menu> getMenulist() {
menu_list = new ArrayList<Menu>();
menu_list.add( new Menu("About Us", " Learn more about our values, mission and vision ") );
menu_list.add( new Menu("Services ", " In implementing its mandate, the Agency will provide the following to its external and internal customers:\n"));
menu_list.add( new Menu("Stakeholders", " Who are the key players, Find out more") );
menu_list.add( new Menu("Learn about Counterfeits", "Gain more insight on counterfeit products"));
return menu_list;
}
and here is my adapter
public class MainMenuAdapter extends RecyclerView.Adapter<MainMenuAdapter.MyViewHolder> {
public List<Menu> list_of_menus;
public MainMenuAdapter( List<Menu> list_of_menus){
this.list_of_menus = list_of_menus;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row,parent, false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Menu menu = list_of_menus.get(position);
Log.e("MENU IN ADAPTER TITLE", menu.title);
holder.title_text.setText( menu.title );
holder.details_text.setText( menu.details );
}
#Override
public int getItemCount() {
return 0;
}
/*
View Holder class
* */
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView title_text, details_text;
public MyViewHolder(View itemView) {
super(itemView);
title_text = (TextView) itemView.findViewById(R.id.menu_title);
details_text = (TextView) itemView.findViewById(R.id.menu_details);
}
}
}
And the Model Class
public class Menu {
public String title, details;
public Menu(String title, String details){
this.details = details;
this.title = title;
}
}
And the layout file main_activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.maos.aca.MainMenuActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="334dp"
android:layout_height="453dp" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp" android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent" android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent" android:id="#+id/main_menu_recycler_view"
android:scrollbars="vertical"/>
</android.support.constraint.ConstraintLayout>
And finally the row
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/menu_title"
android:textStyle="bold"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:id="#+id/menu_details"/>
</LinearLayout>
I know this question has been asked before, but none of the answers helped me out.I'll appreciate any lead.
You need to change the getItemCount() method to this:
#Override
public int getItemCount() {
return list_of_menus.size();
}
The RecyclerView will not display any elements if you are reporting that its size is zero.
Change this:
#Override
public int getItemCount() {
return 0;
}
To this:
#Override
public int getItemCount() {
return list_of_menus.size();
}
In activity_main.xml, I am using TextView with id info to display inforamtion of clicked text in recycler_view list with id item_name. Recycler view is displaying a list of 100 items with its name and toggle to make them active and inactive.
Here is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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"
tools:context="com.app.recyclerviewtesting.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:onClick="eraseInfo"
android:padding="20dp"
android:textColor="#000000"
android:textColorHint="#999999" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager" />
</LinearLayout>
</layout>
Item i.e used in recycler view:
Here is my item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="item"
type="com.app.recyclerviewtesting.Item" />
<variable
name="listener"
type="com.app.recyclerviewtesting.AdapterItemsClickHandler" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<android.support.v7.widget.AppCompatTextView
android:id="#+id/item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:onClick="#{() -> listener.onItemNameClick(item)}"
android:text="#{item.name}"
android:textSize="20sp" />
<ToggleButton
android:id="#+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerHorizontal="true"
android:checked="#{item.on}"
android:onClick="#{() -> listener.onToggleClick(item)}"
tools:ignore="RelativeOverlap" />
</RelativeLayout>
</layout>
Here is MainActivity.java
public class MainActivity extends AppCompatActivity
{
public static final String ITEM_NAME_FORMAT = "Item :%d";
public static final String ITEM_SELECTED_FORMAT = "%s is selected.";
public static final String INFO_HINT = "Click on item!";
private ActivityMainBinding mBinding;
private List<Item> mMainList = new ArrayList<>();
private RecyclerAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
initViews();
}
private void initViews() {
mBinding.info.setHint(INFO_HINT);
for (int i = 0; i < 100; i++) {
mMainList.add(new Item(String.format(Locale.getDefault(), ITEM_NAME_FORMAT, i), false));
}
mAdapter = new RecyclerAdapter(mMainList, new HandleAdapterActions());
mBinding.recyclerView.setAdapter(mAdapter);
}
public void eraseInfo(View view) {
mBinding.info.setText("");
}
private class HandleAdapterActions implements AdapterItemsClickHandler {
#Override
public void onItemNameClick(Item item) {
mBinding.info.setText(String.format(Locale.getDefault(), ITEM_SELECTED_FORMAT, item.getName()));
}
#Override
public void onToggleClick(Item item) {
item.setOn(!item.getOn());
mAdapter.notifyItemChanged(mMainList.indexOf(item));
}
}
}
Here is Adapter
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerView.ViewHolder>
{
private final int ITEM_VIEW_TYPE = 1;
private List<Item> mainList;
private AdapterItemsClickHandler mListener;
public RecyclerAdapter(List<Item> mainList, AdapterItemsClickHandler mListener) {
this.mainList = mainList;
this.mListener = mListener;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
if (viewType == ITEM_VIEW_TYPE) {
final ItemBinding binding = ItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
binding.setListener(mListener);
viewHolder = new ItemViewHolder(binding);
} else {
viewHolder = null;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ItemViewHolder) {
ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
final ItemBinding binding = itemViewHolder.binding;
Item item = mainList.get(position);
binding.setItem(item);
}
}
#Override
public int getItemCount() {
return mainList.size();
}
#Override
public int getItemViewType(int position) {
return ITEM_VIEW_TYPE;
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
public ItemBinding binding;
ItemViewHolder(ItemBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}
Please help me to find the way to write a test case if toggle on position 15th is on or off.
Here is the solution for this problem:
public static Matcher<View> withToggleMatcher(final int position) {
return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
#Override
public void describeTo(Description description) {
}
#Override
protected boolean matchesSafely(RecyclerView recyclerView) {
final RecyclerAdapter.ItemViewHolder viewHolder = (RecyclerAdapter.ItemViewHolder) recyclerView.findViewHolderForAdapterPosition(position);
return viewHolder.binding.toggle.isChecked();
}
};
}
#Test
public void checkIfToggleIsOnAfterClickOnIt() {
int position = 15;
String itemName = String.format(Locale.getDefault(), MainActivity.ITEM_NAME_FORMAT, position);
onView(withId(R.id.recyclerView))
.perform(RecyclerViewActions.scrollToPosition(position));
onView(allOf(withId(R.id.toggle), hasSibling(withText(itemName))))
.perform(click());
onView(withId(R.id.recyclerView))
.check(matches(withToggleMatcher(position)));
}
I am getting data from TMDB API and displaying it on screen.
Right now, I am trying to get reviews from that API.
Everything seems fine, I created: adapter,model,interface,xml and activities, but it is not displaying any data.
API is working fine, I can see from Android Monitor that I am getting right data.
Somebody help, please.
Bellow is my DetailsActivity where I am trying to fetch data:
public class MovieDetailActivity extends AppCompatActivity {
public static final String EXTRA_MOVIE = "EXTRA_MOVIE";
private Movie mMovie;
private Reviews mReviews;
private Genres mGenres;
public ReviewAdapter rAdapter;
ImageView backdrop;
ImageView poster;
TextView title;
TextView description;
TextView releaseDate;
TextView voteAverage;
RecyclerView reviews;
TextView content;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_detail);
if (getIntent().hasExtra(EXTRA_MOVIE)) {
mMovie = getIntent().getParcelableExtra(EXTRA_MOVIE);
} else {
throw new IllegalArgumentException("Detail activity must receive a movie parcelable");
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
CollapsingToolbarLayout toolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
toolbarLayout.setTitle(mMovie.getTitle());
reviews = (RecyclerView) findViewById(R.id.recyclerView2);
reviews.setLayoutManager(new LinearLayoutManager(this));
rAdapter = new ReviewAdapter(MovieDetailActivity.this);
reviews.setAdapter(rAdapter);
getReviews(mMovie.getId());
poster = (ImageView) findViewById(R.id.movie_poster);
String internetUrl = "http://image.tmdb.org/t/p/w500";
Glide.with(this)
.load(mMovie.getPoster())
.into(poster);
Glide.with(this)
.load(mMovie.getBackdrop())
.into(backdrop);
}
private void getReviews(Integer id) {
RestAdapter.getMovieService().getReviews(id, new Callback<ReviewWraper>() {
#Override
public void success(ReviewWraper reviewWraper, Response response) {
rAdapter.setReviewList(reviewWraper.getResults());
}
#Override
public void failure(RetrofitError error) {
error.printStackTrace();
}
});
}
public static class MovieViewHolder extends RecyclerView.ViewHolder {
public ImageView reviewPicture;
public TextView reviewUsername;
public TextView reviewDate;
public TextView reviewTime;
public TextView reviewComment;
public MovieViewHolder(View itemView) {
super(itemView);
reviewPicture = (ImageView) itemView.findViewById(R.id.picture_review);
reviewUsername = (TextView) itemView.findViewById(R.id.username_review);
reviewDate = (TextView) itemView.findViewById(R.id.date_review);
reviewTime = (TextView) itemView.findViewById(R.id.time_review);
reviewComment = (TextView) itemView.findViewById(R.id.review_comment);
}
}
Here is my adapter class:
public class ReviewAdapter extends RecyclerView.Adapter<MovieDetailActivity.MovieViewHolder> {
private List<Reviews> rReviewList;
private LayoutInflater rInflater;
private Context rContext;
public ReviewAdapter(Context context) {
this.rContext = context;
this.rInflater = LayoutInflater.from(context);
this.rReviewList = new ArrayList<>();
}
public MovieDetailActivity.MovieViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
// create a new view
View view = rInflater.inflate(R.layout.row_review, parent, false);
return new MovieDetailActivity.MovieViewHolder(view);
}
#Override
public void onBindViewHolder(MovieDetailActivity.MovieViewHolder holder, int position) {
Reviews reviews = rReviewList.get(position);
Picasso.with(rContext)
.load(reviews.getUrl())
.into(holder.reviewPicture);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Perform click
}
});
}
#Override
public int getItemCount() {
return rReviewList.size();
}
//To update data
public void setReviewList(List<Reviews> reviewsList) {
this.rReviewList = new ArrayList<>();
this.rReviewList.addAll(reviewsList);
notifyDataSetChanged();
}
Bellow is XML 1:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/picture_review"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:adjustViewBounds="true"
android:id="#+id/username_review"
android:layout_width="40dp"
android:layout_height="20dp"
android:width="20dp"
android:height="20dp"
android:textColor="#ffffff" />
<TextView
android:id="#+id/date_review"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#ffffff" />
<TextView
android:id="#+id/time_review"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textColor="#ffffff" />
<TextView
android:id="#+id/review_comment"
android:layout_width="250dp"
android:layout_height="250dp"
android:textColor="#ffffff"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/picture_review"
android:layout_toEndOf="#+id/picture_review" />
</RelativeLayout>
And XML 2 with RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.demo.mtin.mtin.MovieDetailActivity"
tools:showIn="#layout/activity_movie_detail">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#ffffff" />
Try to give fixed height instead of "wrap_content" on your row in root of Xml 1.
tools:showIn="#layout/activity_movie_detail">
If XML 2 needs to show in XML 1, XML1 must have this -
<include layout="#layout/XML2"/>
See this for more details -
android-how-to-use-tools-with-include-layout