I want to display my Pizza & Drink Objects from the Webserver, but my RecyclerView only loads the images directly and the TextViews on Scroll.
I am calling notifyDataSetChanged() for each adapter and even notify the adapters for each of their items with an iteration. I am using Glide to Transform my Images.
Why do my TextViews not load?
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
PizzaDataAdapter pizzaDataAdapter;
DrinkDataAdapter drinkDataAdapter;
CartDataAdapter cartDataAdapter;
ImageView emptyListImageView;
TextView emptyListTextView;
Toolbar mActionBarToolbar;
ConstraintLayout cartIntLayout;
RecyclerView product_recyclerview;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_food:
mActionBarToolbar.setTitle("Pizzas");
FrameLayout pizzas_layout = findViewById(R.id.pizzas_layout);
FrameLayout drinks_layout = findViewById(R.id.drinks_layout);
ConstraintLayout cart_layout = findViewById(R.id.cart_layout);
drinks_layout.setVisibility(GONE);
cart_layout.setVisibility(GONE);
pizzas_layout.setVisibility(View.VISIBLE);
return true;
case R.id.navigation_drinks:
mActionBarToolbar.setTitle("Drinks");
drinks_layout = findViewById(R.id.drinks_layout);
pizzas_layout = findViewById(R.id.pizzas_layout);
cart_layout = findViewById(R.id.cart_layout);
pizzas_layout.setVisibility(GONE);
cart_layout.setVisibility(GONE);
drinks_layout.setVisibility(View.VISIBLE);
return true;
case R.id.navigation_cart:
mActionBarToolbar.setTitle("Cart");
pizzas_layout = findViewById(R.id.pizzas_layout);
drinks_layout = findViewById(R.id.drinks_layout);
cart_layout = findViewById(R.id.cart_layout);
initCartViews();
pizzas_layout.setVisibility(GONE);
drinks_layout.setVisibility(GONE);
cart_layout.setVisibility(View.VISIBLE);
return true;
}
return false;
}
};
public static void start(Context context) {
Intent starter = new Intent(context, MainActivity.class);
context.startActivity(starter);
}
#Override
protected void onCreate(Bundle savedInstanceState) throws NullPointerException {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cartIntLayout = findViewById(R.id.cart_int_layout);
cartIntLayout.bringToFront();
mActionBarToolbar = findViewById(R.id.my_toolbar);
mActionBarToolbar.setTitle("Pizzas");
mActionBarToolbar.setTitleTextColor(getResources().getColor(R.color.white, this.getTheme()));
setSupportActionBar(mActionBarToolbar);
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
PizzaLoadingTask.TaskListener pizzaListener = new PizzaLoadingTask.TaskListener() {
#Override
public void onComplete(List<Pizza> pizzas) {
if (pizzas.isEmpty()) {
initViewsWithEmptyList();
}
initPizzaViews(pizzas);
}
};
new PizzaLoadingTask(pizzaListener, APIClient.getInstance()).execute();
DrinkLoadingTask.TaskListener drinkListener = new DrinkLoadingTask.TaskListener() {
#Override
public void onComplete(List<Drink> drinks) {
if (drinks.isEmpty()) {
initViewsWithEmptyList();
}
initDrinkViews(drinks);
}
};
new DrinkLoadingTask(drinkListener, APIClient.getInstance()).execute();
}
private void initPizzaViews(List<Pizza> pizzas) {
pizzaDataAdapter = new PizzaDataAdapter(pizzas);
recyclerView = findViewById(R.id.card_recycler_view_pizzas);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(getBaseContext(),
DividerItemDecoration.VERTICAL));
pizzaDataAdapter.notifyDataSetChanged();
recyclerView.setAdapter(pizzaDataAdapter);
}
private void initDrinkViews(List<Drink> drinks) {
recyclerView = findViewById(R.id.card_recycler_view_drinks);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(getBaseContext(),
DividerItemDecoration.VERTICAL));
drinkDataAdapter = new DrinkDataAdapter(drinks);
drinkDataAdapter.notifyDataSetChanged();
recyclerView.setAdapter(drinkDataAdapter);
}
private void initCartViews() {
product_recyclerview = findViewById(R.id.cart_products_recyclerview);
product_recyclerview.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
product_recyclerview.setLayoutManager(layoutManager);
cartDataAdapter = new CartDataAdapter(pizzaDataAdapter.getCartPizzas(), drinkDataAdapter.getCartDrinks());
product_recyclerview.setAdapter(cartDataAdapter);
}
private void initViewsWithEmptyList() {
recyclerView = findViewById(R.id.card_recycler_view_drinks);
recyclerView.setVisibility(GONE);
emptyListImageView = findViewById(R.id.pizza_image_empty_list);
emptyListTextView = findViewById(R.id.pizza_empty_textview);
emptyListImageView.setVisibility(View.VISIBLE);
emptyListTextView.setVisibility(View.VISIBLE);
}
#Override
public void onBackPressed() {
super.onBackPressed();
SharedPreferences preferences = getSharedPreferences("loginRecognizer", MODE_PRIVATE);
if (preferences.contains("loggedIn")) {
Intent i = new Intent(this, LoginActivity.class); // Your list's Intent
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); // Adds the FLAG_ACTIVITY_NO_HISTORY flag
startActivity(i);
}
}
}
PizzaDataAdapter.java (DrinkDataAdapter same but just with Drink-Objects)
public class PizzaDataAdapter extends RecyclerView.Adapter<PizzaDataAdapter.ViewHolder> {
private List<Pizza> pizzas;
//TODO implement cartDrinks LinkedList
private List<Pizza> cartPizzas = new LinkedList<>();
PizzaDataAdapter(List<Pizza> pizzas) {
this.pizzas = pizzas;
}
private static BigDecimal round(float d) {
BigDecimal bd = new BigDecimal(Float.toString(d));
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
return bd;
}
#Override
public PizzaDataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.pizza_card_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(PizzaDataAdapter.ViewHolder viewHolder, int position) {
final Pizza pizza = pizzas.get(position);
// viewHolder.setIsRecyclable(false);
//viewHolder.pizza_image.setText(pizzas.get(i).getId().toString());
viewHolder.pizza_name.setText(pizza.getName());
BigDecimal result = round(pizza.getPrice());
String price = "Price: " + result.toString();
viewHolder.pizza_price.setText(price);
GlideApp.with(viewHolder.pizza_image.getContext())
.load(pizzas.get(position).getImagepath())
.apply(RequestOptions.circleCropTransform())
.into(viewHolder.pizza_image);
viewHolder.pizza_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(viewHolder.pizza_layout.getContext(), PizzaDetailActivity.class);
intent.putExtra("Name", pizzas.get(position).getName());
intent.putExtra("Price", pizzas.get(position).getPrice());
intent.putExtra("Ingredients", pizzas.get(position).getIngredients());
viewHolder.pizza_layout.getContext().startActivity(intent);
}
});
viewHolder.plus_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cartPizzas.add(pizzas.get(position));
}
});
}
#Override
public int getItemCount() {
return pizzas.size();
}
public List<Pizza> getCartPizzas() {
return cartPizzas;
}
class ViewHolder extends RecyclerView.ViewHolder {
private ImageView pizza_image;
private TextView pizza_name, pizza_price;
private ImageButton plus_button;
private ConstraintLayout pizza_layout;
ViewHolder(View view) {
super(view);
pizza_image = view.findViewById(R.id.pizza_image);
pizza_name = view.findViewById(R.id.pizza_name);
pizza_price = view.findViewById(R.id.pizza_price);
plus_button = view.findViewById(R.id.pizza_plus_button);
pizza_layout = view.findViewById(R.id.pizza_card_row_layout);
}
}
}
PizzaLoadingTask.java
public class PizzaLoadingTask extends AsyncTask<Void, Void, List<Pizza>> {
private APIClient apiClient;
private TaskListener mListener;
public PizzaLoadingTask(TaskListener listener, APIClient apiClient){
this.mListener=listener;
this.apiClient = apiClient;
}
#Override
protected List<Pizza> doInBackground(Void... voids) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(APIInterface.baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIInterface request = retrofit.create(APIInterface.class);
Call<List<Pizza>> call = request.getPizzas();
try {
Response<List<Pizza>> jsonResponse = call.execute();
return jsonResponse.body();
// return Collections.emptyList();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
#Override
protected void onPostExecute(List<Pizza> pizzas) {
mListener.onComplete(pizzas);
}
public interface TaskListener {
void onComplete(List<Pizza> pizzas);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".screens.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.constraint.ConstraintLayout
android:id="#+id/navigation_layout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/my_toolbar"
app:layout_constraintVertical_bias="0.0">
<include
android:id="#+id/pizzas_layout"
layout="#layout/pizza_products"
android:visibility="visible" />
<include
android:id="#+id/drinks_layout"
layout="#layout/drink_products"
android:visibility="invisible" />
<include
android:id="#id/cart_layout"
layout="#layout/product_cart"
android:visibility="invisible" />
</android.support.constraint.ConstraintLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation">
</android.support.design.widget.BottomNavigationView>
<android.support.constraint.ConstraintLayout
android:id="#+id/cart_int_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="57dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#id/navigation">
<TextView
android:id="#+id/cart_int_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
pizza_products.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pizza_products_layout"
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="com.apprentice.ti8m.myfirstrestclient.screens.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/card_recycler_view_pizzas"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp"
tools:listitem="#layout/pizza_card_row">
</android.support.v7.widget.RecyclerView>
<android.support.constraint.ConstraintLayout
android:id="#+id/pizza_image_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<ImageView
android:id="#+id/pizza_image_empty_list"
android:layout_width="256dp"
android:layout_height="256dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="#+id/pizza_empty_textview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.176"
app:layout_constraintVertical_chainStyle="spread"
app:srcCompat="#drawable/ic_pizza_empty_list"
tools:visibility="visible"
android:contentDescription="#string/image_to_show_up_if_pizza_list_is_empty" />
<TextView
android:id="#+id/pizza_empty_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/pizza_list_empty"
android:visibility="gone"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/pizza_image_empty_list"
app:layout_constraintVertical_bias="0.567"
tools:visibility="visible" />
</android.support.constraint.ConstraintLayout>
</FrameLayout>
pizza_card_row.xml
<android.support.constraint.ConstraintLayout
android:id="#+id/pizza_card_row_layout"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="72dp">
<ImageView
android:id="#+id/pizza_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="#+id/pizza_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="0dp"
android:fontFamily="sans-serif"
android:textSize="16sp"
android:textColor="#color/colorPizzaName"
app:layout_constraintHorizontal_bias="0.1"
app:layout_constraintLeft_toRightOf="#+id/pizza_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="#+id/pizza_image" />
<TextView
android:id="#+id/pizza_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="-1dp"
app:layout_constraintBottom_toBottomOf="#+id/pizza_image"
app:layout_constraintLeft_toRightOf="#+id/pizza_image"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:fontFamily="sans-serif"
android:textSize="14sp"
app:layout_constraintRight_toRightOf="parent" />
<ImageButton
android:id="#+id/pizza_plus_button"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="72dp"
android:layout_height="0dp"
android:layout_gravity="center"
android:src="#drawable/ic_add_black_24dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="#string/plus_button_for_each_recyclerview_card" />
</android.support.constraint.ConstraintLayout>
try remove this unnecessary code:
for (int i = 0; i< pizzas.size(); i++){
pizzaDataAdapter.notifyItemInserted(i);
}
since recyclerview adapter set after data complete/loaded in adapter
Related
I want to integrate my chatbot(created by dialogflow) to my apps and I have create the xml files but I didn't find a way how to match between them.
I have already database using room library persistance .And, I'm coding with Java.
How can I itegrate my agent into my apps?And how to add a recylerViewAdapter for my chatmessages.
Thank you
msg_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/leftText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_alignParentStart="true"
android:text="Hello this is me!!"
android:padding="8dp"
android:textColor="#212121"
android:background="#drawable/left_background"
android:elevation="2dp"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/rightText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_alignParentEnd="true"
android:text="Hi!! How are you!!"
android:background="#drawable/right_background"
android:textColor="#fff"
android:padding="8dp"
android:elevation="2dp"
android:layout_alignParentRight="true" />
</RelativeLayout>
Chatbot.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=".Chatbot">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dp"
android:paddingBottom="50dp"
android:clipToPadding="false"
android:background="#f4f6f7"
tools:listitem="#layout/msglist"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="10dp"
android:elevation="2dp"
android:layout_toStartOf="#+id/addBtn"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_toLeftOf="#+id/addBtn">
<EditText
android:id="#+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:background="#fff"
android:hint="Type a Message"
android:minHeight="50dp"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/addBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:background="#drawable/back_fab"
android:layout_marginBottom="10dp"
android:layout_marginEnd="5dp"
android:elevation="4dp"
android:layout_centerInParent="true"
android:layout_alignParentRight="true"
android:layout_marginRight="5dp">
<ImageView
android:id="#+id/fab_img"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerInParent="true"
android:src="#drawable/ic_send_white_24dp"
android:tint="#fff"/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
ChatbotActivity
public class Chatbot extends AppCompatActivity implements AIListener {
RecyclerView recyclerView;
EditText message;
RelativeLayout addBtn;
ChatbotAdapter adapter;
Boolean flagFab = true;
private AIService aiService;
private AIServiceContext customAIServiceContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatbot);
recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
message = (EditText)findViewById(R.id.message);
addBtn = (RelativeLayout)findViewById(R.id.addBtn);
recyclerView.setHasFixedSize(true);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = message.getText().toString().trim();
if (!message.equals("")) {
ChatMessage chatMessage = new ChatMessage(msg, "user");
}
message.setText("");
}
});
adapter = new ChatbotAdapter();
recyclerView.setAdapter(adapter);
final AIConfiguration config = new AIConfiguration("Acces",
AIConfiguration.SupportedLanguages.French,
AIConfiguration.RecognitionEngine.System);
aiService = AIService.getService(this, config);
customAIServiceContext = AIServiceContextBuilder.buildFromSessionId("ID");
aiService.setListener(this);
final AIDataService aiDataService = new AIDataService(config);
final AIRequest aiRequest = new AIRequest();
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = message.getText().toString().trim();
if (!msg.equals("")) {
aiRequest.setQuery(msg);
new AsyncTask<AIRequest,Void, AIResponse>(){
#Override
protected AIResponse doInBackground(AIRequest... aiRequests) {
final AIRequest request = aiRequests[0];
try {
final AIResponse response =
aiDataService.request(aiRequest);
return response;
} catch (AIServiceException e) {
}
return null;
}
#Override
protected void onPostExecute(AIResponse response) {
if (response != null) {
Result result = response.getResult();
String reply = result.getFulfillment().getSpeech();
}
}
}.execute(aiRequest);
}
else {
aiService.startListening();
}
message.setText("");
}
});
}
#Override
public void onResult(AIResponse response) {
}
#Override
public void onError(AIError error) {
}
#Override
public void onAudioLevel(float level) {
}
#Override
public void onListeningStarted() {
}
#Override
public void onListeningCanceled() {
}
#Override
public void onListeningFinished() {
}
}
Chatmessage
public class ChatMessage {
private String msgText;
private String msgUser;
public ChatMessage(String msgText, String msgUser){
this.msgText = msgText;
this.msgUser = msgUser;
}
public ChatMessage(){
}
//+getter & setter
}
ChatbotAdapter
//I don't know how to code this class
public class ChatbotAdapter extends RecyclerView.Adapter<ChatbotAdapter.ChatHolder>
{
#NonNull
#Override
public ChatHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.msglist, viewGroup, false);
return new ChatHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ChatHolder chatHolder, int i) {
}
#Override
public int getItemCount() {
return 0;
}
public class ChatHolder extends RecyclerView.ViewHolder {
TextView leftText, rightText;
public ChatHolder(View itemView) {
super(itemView);
leftText = (TextView) itemView.findViewById(R.id.leftText);
rightText = (TextView) itemView.findViewById(R.id.rightText);
}
}
}
Your question is not that clear. Please add some more details like what is you want, what you have implemented and what issue is coming.
You may also try my implementation. I am not using Recycler view in my implementation, but you could follow the following article I wrote for integrating Dialogflow with Android. Try an follow the V2 version as V1 will phase out by October this year.
Also, Do not use fragment for Chatbot as it somehow does not work. Try and make a simple chatbot using my implementation and then you can work towards your own implementation.
Hope it works.
My RecyclerView doesn't show any value in alert dialog. I am confused and don't know where should I looking for a problem in my code. I hope some of you guys met with same issue.
This is activity where I am calling my RecycleView andl AlertDialog.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pondeljak = (Button) findViewById(R.id.buttonPonedeljak);
utorak = (Button) findViewById(R.id.buttonUtorak);
sreda = (Button) findViewById(R.id.buttonSreda);
cetvrtak = (Button) findViewById(R.id.buttonCetvrtak);
petak = (Button) findViewById(R.id.buttonPetak);
db = new DataDays(this);
View view = getLayoutInflater().inflate(R.layout.casovi,null);
alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setView(view);
alertDialog = alertDialogBuilder.create();
recyclerView = (RecyclerView) view.findViewById(R.id.recycleCasoviID);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
casoviList = new ArrayList<>();
casoviItems = new ArrayList<>();
// for (Casovi c: casoviList){
Casovi casovi = new Casovi();
//casovi.setId(0);
casovi.setDan("asas");
casovi.setRedniBrCasa("ssss");
casovi.setNzaivCasa("ssddff");
casoviItems.add(casovi);
recycleViewAdapter = new RecycleViewAdapter(this, casoviItems);
recyclerView.setAdapter(recycleViewAdapter);
recycleViewAdapter.notifyDataSetChanged();
pondeljak.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (db.casoviCountPondeljak() == 0){
Intent intent = new Intent(MainActivity.this, Unos_casova.class);
intent.putExtra("Dan", "Pondeljak");
startActivity(intent);
}else {
alertDialog.show();
}
This is RecycleView class. I am not sure, maybe here is some problem?
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder> {
private Context context;
private List<Casovi> casoviItems;
public RecycleViewAdapter(Context context, List<Casovi> casoviItems) {
this.context = context;
this.casoviItems = casoviItems;
}
#Override
public RecycleViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.prikaz_casova, parent,false);
return new ViewHolder(view, context);
}
#Override
public void onBindViewHolder( RecycleViewAdapter.ViewHolder holder, int position) {
Casovi casovi = new Casovi();
holder.redniBrCasPrikaz.setText(casovi.getRedniBrCasa());
holder.nazivCasPrikaz.setText(casovi.getRedniBrCasa());
}
#Override
public int getItemCount() {
return casoviItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView redniBrCasPrikaz;
public TextView nazivCasPrikaz;
public Button delteBtn;
public Button editBtn;
public CardView cardView;
public ViewHolder(View view, Context ctx) {
super(view);
context = ctx;
redniBrCasPrikaz = (TextView) view.findViewById(R.id.rednibrojCasaID);
nazivCasPrikaz = (TextView) view.findViewById(R.id.nazivcasaID);
delteBtn = (Button) view.findViewById(R.id.obrisiCasBtnID);
editBtn = (Button) view.findViewById(R.id.izmeniCasBtnID);
cardView = (CardView) view.findViewById(R.id.carViewID);
}
}
Layout casovi. That RecycleView on witch prikaz casova should be attached.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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.support.v7.widget.RecyclerView
android:id="#+id/recycleCasoviID"
android:layout_width="match_parent"
android:layout_height="574dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.283" />
</android.support.constraint.ConstraintLayout>
Layout prikaz_casova. This layout should show values from db. In this exemple I've posted there is hadrdoced values tho be showen.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<android.support.v7.widget.CardView
android:id="#+id/carViewID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="133dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="470dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.471">
<RelativeLayout
android:id="#+id/relativniID"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/rednibrojCasaID"
android:layout_width="126dp"
android:layout_height="wrap_content"
android:text="redni broj casa"
android:textSize="14dp"
android:textStyle="italic"
/>
<TextView
android:id="#+id/nazivcasaID"
android:layout_width="338dp"
android:layout_height="105dp"
android:layout_below="#+id/rednibrojCasaID"
android:layout_marginTop="1dp"
android:text="Naziv casa"
android:textSize="24dp"
android:textStyle="bold" />
<Button
android:id="#+id/obrisiCasBtnID"
android:layout_width="40dp"
android:layout_height="37dp"
android:layout_below="#+id/rednibrojCasaID"
android:layout_toRightOf="#+id/nazivcasaID"
android:background="#drawable/delete" />
<Button
android:id="#+id/izmeniCasBtnID"
android:layout_width="40dp"
android:layout_height="37dp"
android:layout_below="#+id/obrisiCasBtnID"
android:layout_marginLeft="3dp"
android:layout_marginTop="15dp"
android:layout_toRightOf="#+id/nazivcasaID"
android:background="#drawable/edit" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
Here the error you made, in your RecyclerView Adapter class.
#Override
public void onBindViewHolder( RecycleViewAdapter.ViewHolder holder, int position) {
Casovi casovi = new Casovi();
It should be
Casovi casovi = casoviItems.get(position);
holder.redniBrCasPrikaz.setText(casovi.getRedniBrCasa());
holder.nazivCasPrikaz.setText(casovi.getRedniBrCasa());
}
You are all done
Am trying to build my first app and my recyclerView only displays the first item from the json.I have tried changing the layout height to wrap_content but its still not working
Here is the xml layout for the recyclerview activity
<?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="wrap_content"
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.example.aleky.carrental.cars">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/rv"
android:clickable="false"
/>
</RelativeLayout>
</RelativeLayout>
the cardview xml layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
cardview:cardCornerRadius="2dp"
cardview:cardElevation="3dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:paddingBottom="15dp">
<TextView
android:id="#+id/car_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp"
android:fontFamily="sans-serif-smallcaps"
android:text="Car Name"
android:textColor="#996515"
android:textSize="24sp"
android:textStyle="bold" />
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/Car_image"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_below="#+id/car_name"
android:layout_marginBottom="2dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="2dp" />
<TextView
android:id="#+id/tvfeature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="90dp"
android:layout_marginTop="25dp"
android:layout_toRightOf="#+id/car_name"
android:text="Features"
android:textColor="#000"
android:textSize="22sp" />
<View
android:layout_width="100dp"
android:layout_height="1dp"
android:layout_below="#+id/tvfeature"
android:layout_marginLeft="20dp"
android:layout_toRightOf="#+id/Car_image"
android:background="#000" />
<ImageView
android:id="#+id/ac"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="#+id/tvfeature"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="#+id/Car_image"
android:src="#drawable/air_conditioner" />
<TextView
android:id="#+id/feature1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tvfeature"
android:layout_marginTop="10dp"
android:layout_toRightOf="#+id/ac"
android:text="Air conditioner"
android:textColor="#000"
android:textSize="16sp" />
<ImageView
android:id="#+id/tr"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="#+id/feature1"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="#+id/Car_image"
android:src="#drawable/transmission" />
<TextView
android:id="#+id/feature2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/feature1"
android:layout_marginLeft="2dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="#+id/tr"
android:text="Manual"
android:textColor="#333333"
android:textSize="16sp" />
<ImageView
android:id="#+id/pass"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="#+id/tr"
android:layout_marginLeft="20dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="#+id/Car_image"
android:src="#drawable/passengers" />
<TextView
android:id="#+id/feature3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/feature2"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="#id/pass"
android:text="6 Passengers"
android:textColor="#333333"
android:textSize="16sp" />
<TextView
android:id="#+id/pricetxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/Car_image"
android:text="Price :"
android:textColor="#333333"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:id="#+id/car_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/Car_image"
android:layout_marginLeft="2dp"
android:layout_toRightOf="#+id/pricetxt"
android:text="KSH.2000"
android:textColor="#996515"
android:textSize="22sp" />
<TextView
android:id="#+id/organiser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/pricetxt"
android:layout_marginTop="5dp"
android:text="Owner :"
android:textColor="#333333"
android:textSize="14sp" />
<TextView
android:id="#+id/crAgent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/pricetxt"
android:layout_marginLeft="2dp"
android:layout_marginTop="5dp"
android:layout_toEndOf="#+id/organiser"
android:layout_toRightOf="#+id/organiser"
android:text="Supercars Rentals"
android:textColor="#05056c"
android:textSize="14sp" />
<Button
android:id="#+id/btn_rent"
style="#style/AppTheme.ButtonCorners"
android:layout_width="150dp"
android:layout_height="40dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/Car_image"
android:layout_marginRight="12dp"
android:clickable="true"
android:text="Rent"
android:textColor="#eef525" />
<TextView
android:id="#+id/car_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
</RelativeLayout>
</android.support.v7.widget.CardView>
The cars.java class to load items into the recyclerview
public class cars extends AppCompatActivity {
String url = "http://192.168.43.201/Car_rental/retrievecars.php";
Context context = null;
ProgressDialog dialog;
private List<CarsItem> array_cars = new ArrayList<>();
AdapterClass adapter;
NetworkImageView carsImageview;
private String user_Location = "cLocation";
private String Category = "category";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cars);
adapter = new AdapterClass(cars.this, array_cars);
RecyclerView recycler = (RecyclerView) findViewById(R.id.rv);
recycler.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recycler.setLayoutManager(layoutManager);
recycler.setItemAnimator(new DefaultItemAnimator());
recycler.setAdapter(adapter);
setCars();
recycler.addOnItemTouchListener(new RecyclerTouchListener(this, recycler, new ClickListener() {
#Override
public void onClick(View view, int position) {
}
#Override
public void onLongClick(View view, int position) {
}
}));
}
public void setCars() {
dialog = new ProgressDialog(this);
dialog.setMessage("Loading cars...");
dialog.show();
if (array_cars != null) {
array_cars.clear();
}
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String s) {
try {
hideDialog();
Log.d("Sever Message", s);
JSONObject cars = new JSONObject(s);
JSONArray jsonArray = cars.getJSONArray("Cars");
JSONObject jobject = null;
int len = jsonArray.length();
for (int i = 0; i < len; i++) {
jobject = jsonArray.getJSONObject(i);
CarsItem carsdata = new CarsItem();
carsdata.setId(jobject.getString("0"));
carsdata.setCarname(jobject.getString("1"));
carsdata.setImages(jobject.getString("car_image"));
carsdata.setfeature1(jobject.getString("5"));
carsdata.setfeature2(jobject.getString("6"));
carsdata.setfeature3(jobject.getString("7"));
carsdata.setPrice(jobject.getString("8"));
array_cars.add(carsdata);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
//Getting Image Location & category
String Location = "";
String Ccategory = "cars";
//Creating parameters
Map<String, String> params = new Hashtable<String, String>();
//Adding parameters
params.put(Category, Ccategory);
params.put(user_Location, Location);
//returning parameters
return params;
}
};
//RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding our request to the queue
// requestQueue.add(request);
AppController.getmInstance().addToRequestQueue(request);
}
public void hideDialog() {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
GestureDetector gestureDetector;
cars.ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final cars.ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView recycler, MotionEvent e) {
View child = recycler.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, recycler.getChildPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView recycler, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}
and finally my adapter class
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.CustomViewHolder> {
private List<CarsItem> Array_cars;
private ImageLoader imageLoader;
private Context mContext;
public AdapterClass(Context context, List<CarsItem> array_cars) {
this.Array_cars = array_cars;
this.mContext = context;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cars_design, null);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(CustomViewHolder holder,final int i) {
final CarsItem carsItem = Array_cars.get(i);
holder.imageUrl = carsItem.getImages();
imageLoader = AppController.getmInstance().getmImageLoader();
holder.Carname.setText(carsItem.getCarname());
holder.feature1.setText(carsItem.getfeature1());
holder.feature2.setText(carsItem.getfeature2());
holder.feature3.setText(carsItem.getfeature3());
holder.price.setText(carsItem.getPrice());
holder.agent.setText(carsItem.getcarowner());
holder.carid.setText(carsItem.getId());
holder.carimage.setImageUrl("http://192.168.43.201/Car_rental/cars/"+carsItem.getImages(), imageLoader);
holder.rent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, HireCar.class);
intent.putExtra("carname",carsItem.getCarname());
intent.putExtra("car_rate",carsItem.getPrice());
intent.putExtra("car_image", carsItem.getImages());
intent.putExtra("car_id", carsItem.getId());
intent.putExtra("c_owner", carsItem.getcarowner());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return (null != Array_cars ? Array_cars.size() : 0);
}
class CustomViewHolder extends RecyclerView.ViewHolder {
String imageUrl;
TextView Carname, feature1, feature2, feature3, price,agent,carid;
NetworkImageView carimage;
Button rent;
public CustomViewHolder(View view) {
super(view);
this.Carname = (TextView) view.findViewById(R.id.car_name);
this.feature1 = (TextView) view.findViewById(R.id.feature1);
this.feature3 = (TextView) view.findViewById(R.id.feature3);
this.price = (TextView) view.findViewById(R.id.car_price);
this.feature2=(TextView) view.findViewById(R.id.feature2);
this.carimage = (NetworkImageView) view.findViewById(R.id.Car_image);
this.rent=(Button)view.findViewById(R.id.btn_rent);
this.agent=(TextView)view.findViewById(R.id.crAgent);
this.carid=(TextView)view.findViewById(R.id.car_id);
}
}
}
I think the problem is that you are not adding the elements to the adapter. You need to have a method in the adapter to add items after the adapter has been created. Inside that method you need to notify. Example:
void addItems(List<CarItem> carItems){
Array_cars.addAll(carItems);
notifyDataSetChanged();
}
However, I would go a bit far and find the number of items and try to notify only for the newly inserted ones(in case there is something already).
This can be done like this:
void addItems(List<CarItem> carItems){
int position = Array_cars.size();
Array_cars.addAll(carItems);
notifyItemRangeChanged(position, Array_cars.size() - position);
}
EDIT
Look at this example below:
RecycleView
Here is the xml layout for the recyclerview activity
<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.example.aleky.carrental.cars">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rv"
android:clickable="false"
/>
</RelativeLayout>
</RelativeLayout>
You have added match_parent height of "RecyclerView" please change to wrap_content.
<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.example.aleky.carrental.cars">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/rv"
android:clickable="false"
/>
</RelativeLayout>
</RelativeLayout>
May sound like a duplicate issue but have checked the issues posted which is either related to the getItemCount() not set or layout height/width issues.
I'm using a CardView as RecyclerView Item . The adapter fetches 60 records (checked the count )but the CardView is not even shown neither the data .
Using ConstraintLayout in which I'm still a newbie, the design view it shows perfectly. The data is being populated from external APIs and using retrofit library which is working fine.
Activity xml.
<android.support.constraint.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"
android:scrollbars="vertical"
tools:context="com.techn.rails.Activity.TrainStatus">
/>
<android.support.v7.widget.CardView
android:id="#+id/search_cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:cardElevation="5dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp">
<android.support.v7.widget.AppCompatTextView
android:id="#+id/trainno_search_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Train Number"
app:layout_constraintEnd_toStartOf="#+id/trainno_search_et"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_weight="1"
/>
<android.support.v7.widget.AppCompatEditText
android:id="#+id/trainno_search_et"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#id/trainno_search_tv"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBaseline_toBaselineOf="#+id/trainno_search_tv"
android:inputType="number"
android:maxLength="6"
android:hint="#string/train_number"
app:layout_constraintHorizontal_weight="1.5"
/>
<android.support.v7.widget.AppCompatEditText
android:id="#+id/doj_et"
android:layout_width="0dp"
app:layout_constraintEnd_toEndOf="#id/trainno_search_tv"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/trainno_search_tv"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="12dp"
/>
<android.support.v7.widget.AppCompatButton
android:id="#+id/doj_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="#+id/doj_et"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/trainno_search_et"
app:layout_constraintBaseline_toBaselineOf="#+id/doj_et"
android:layout_marginTop="12dp"
android:text="#string/select_date"
/>
<android.support.v7.widget.AppCompatButton
android:id="#+id/submit"
android:layout_width="100dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/doj_btn"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="#string/submit_btn"
/>
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.RecyclerView
android:id="#+id/train_list"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/result_cardview"
app:layout_constraintBottom_toBottomOf="parent"
android:scrollbars="vertical"
android:padding="10dp"
android:layout_margin="10dp"></android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
Cardview xml
<android.support.constraint.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">
<android.support.v7.widget.CardView
android:id="#+id/train_status_card_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_gravity="center"
android:layout_margin="5dp"
android:elevation="5dp"
app:cardCornerRadius="5dp"
android:background="?android:attr/selectableItemBackground">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.AppCompatTextView
android:id="#+id/train_stn_code_lbl"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<android.support.v7.widget.AppCompatTextView
android:id="#+id/train_stn_code"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="#id/train_stn_code_lbl"
app:layout_constraintRight_toRightOf="parent" />
<android.support.v7.widget.AppCompatTextView
android:id="#+id/train_sch_arr_lbl"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toBottomOf="#id/train_stn_code_lbl"
app:layout_constraintLeft_toLeftOf="parent"
/>
<android.support.v7.widget.AppCompatTextView
android:id="#+id/train_sch_arr"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toBottomOf="#id/train_stn_code"
app:layout_constraintLeft_toRightOf="#id/train_sch_arr_lbl"
app:layout_constraintRight_toRightOf="parent" />
<android.support.v7.widget.AppCompatTextView
android:id="#+id/train_act_dep_lbl"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toBottomOf="#id/train_sch_arr_lbl"
app:layout_constraintLeft_toLeftOf="parent"
/>
<android.support.v7.widget.AppCompatTextView
android:id="#+id/train_act_dep"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toBottomOf="#id/train_sch_arr_lbl"
app:layout_constraintLeft_toRightOf="#id/train_act_dep_lbl"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
Activity
public class TrainStatus extends AppCompatActivity implements DatePickerDialog.OnDateSetListener {
#BindView(R.id.doj_btn)
AppCompatButton mDojBtn;
#BindView(R.id.trainno_search_et)
AppCompatEditText mTrainNumber;
#BindView(R.id.submit)
AppCompatButton mSubmit;
#BindView(R.id.train_list)
RecyclerView recyclerView;
private Calendar calendar;
private DatePickerDialog datePickerDialog;
int Year, Month, Day ;
String dateSelected, dateToDisplay;
private TrainStatusRoute mAdapter;
private List<Route> mRoutes;
private static final String TAG = TrainStatus.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_train_status);
ButterKnife.bind(this);
mRoutes = new ArrayList<>();
mAdapter = new TrainStatusRoute(this,mRoutes);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mAdapter);
calendar = Calendar.getInstance();
Year = calendar.get(Calendar.YEAR) ;
Month = calendar.get(Calendar.MONTH);
Day = calendar.get(Calendar.DAY_OF_MONTH);
mDojBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
datePickerDialog = DatePickerDialog.newInstance(TrainStatus.this, Year, Month, Day);
datePickerDialog.setThemeDark(false);
datePickerDialog.showYearPickerFirst(false);
}
});
mSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
requestAPIQuery(mTrainNumber.getText().toString(),dateSelected);
}
});
}
#Override
public void onDateSet(DatePickerDialog view, int Year, int Month, int Day) {
dateSelected = String.valueOf(Year)+String.valueOf(Month + 1)+String.valueOf(Day);
}
private void requestAPIQuery (String trainNumber, String doj){
IApi apiService = APIClient.getClient().create(IApi.class);
Call<TrainStatus> call = apiService.getTrainStatus(trainNumber,doj,API_KEY);
call.enqueue(new Callback<TrainStatus>() {
#Override
public void onResponse(Call<TrainStatus> call, Response<TrainStatus> response) {
List<Route> trainStatuses = response.body().getRoute();
mAdapter.notifyDataSetChanged();
Log.d(TAG,"Number of trains"+trainStatuses.size());//getting count 60 here
}
#Override
public void onFailure(Call<com.technovibe.railstat.Model.TrainStatus> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
}
}
Adapter code
public class TrainStatusRoute extends RecyclerView.Adapter<TrainStatusRoute.RouteViewHolder> {
private Context mContext;
private List<Route> mRoutes;
public static class RouteViewHolder extends RecyclerView.ViewHolder{
#BindView(R.id.train_act_arr)
TextView mActArr;
#BindView(R.id.train_act_dep)
TextView mActDep;
#BindView(R.id.train_sch_arr)
TextView mSchArr;
#BindView(R.id.train_sch_dep)
TextView mSchDep;
public RouteViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
public TrainStatusRoute(Context context, List<Route> routeList) {
this.mContext = context;
this.mRoutes = routeList;
}
#Override
public TrainStatusRoute.RouteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.train_status_card, parent, false);
return new RouteViewHolder(itemView);
}
#Override
public void onBindViewHolder(TrainStatusRoute.RouteViewHolder holder, int position) {
Route route = mRoutes.get(position);
holder.mActArr.setText(route.getActarr());
holder.mActDep.setText(route.getActdep());
holder.mSchDep.setText(route.getSchdep());
holder.mSchArr.setText(route.getScharr());
}
#Override
public int getItemCount() {
return mRoutes.size();
}
}
Please bear with me posting lengthy code.
Appreciate any help , thanks in advance.
I guess the problem could be in the card view's width and heights:
<android.support.v7.widget.CardView
android:id="#+id/search_cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
Try changing the width and height values to let's say width match_parent and height to 60 dp and see if the items will appear.
public void onResponse(Call<TrainStatus> call, Response<TrainStatus> response) {
List<Route> trainStatuses = response.body().getRoute();
//Add this line here
mAdapter.setRoutes(trainStatuses);
mAdapter.notifyDataSetChanged();
Log.d(TAG,"Number of trains"+trainStatuses.size());//getting count 60 here
}
And define a setter for your list in your adapter
public void setRoutes(List<Route> routes){
mRoutes = routes;
}
I have a problem with my layout. I'm trying to do something like this:
For now, i have a RecyclerView with a CardView inside it. in the CardView I have put an ImageView and a TextView but I don't know why but the CardView is more height than ImageView inside it.
Here is The code and a Sample Image.
And Here is the code: Activity
public class AddRoomActivity extends AppCompatActivity implements View.OnClickListener {
private View snackView;
private FloatingActionButton fabDoneAddRoom;
private EditText etRoomName;
private String roomName = null;
public final static String KEY_PI_IP = "MyPi_IP";
private final static String KEY_ROOM = "myRoom";
private final static String KEY_ROOM_TYPE = "myRoom_Type";
private RecyclerView typeRecyclerView;
private GridLayoutManager layoutManager;
private AddRoomActivity.TypeAdapter adapter;
private String myPi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_room);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fabDoneAddRoom = (FloatingActionButton) findViewById(R.id.doneAddRoom);
fabDoneAddRoom.setOnClickListener(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
etRoomName = (EditText) findViewById(R.id.addRoomName);
myPi = getIntent().getStringExtra(KEY_PI_IP);
layoutManager = new GridLayoutManager(this, 2);
typeRecyclerView = (RecyclerView) findViewById(R.id.recyclerTypeRoom);
typeRecyclerView.setHasFixedSize(true);
typeRecyclerView.setLayoutManager(layoutManager);
// specify an adapter (see also next example)
adapter = new TypeAdapter(getResources().getStringArray(R.array.roomTypeName));
typeRecyclerView.setAdapter(adapter);
}
void showToastMessage(String message) {
Snackbar.make(snackView, message, Snackbar.LENGTH_LONG).show();
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.doneAddRoom) {
snackView = v;
String myString = etRoomName.getText().toString();
if (myString.length() > 0) {
roomName = myString.substring(0, 1).toUpperCase() + myString.substring(1);
addRoomToPi();
} else {
showToastMessage(getString(R.string.noNameRoom));
}
}
}
private void addRoomToPi() {
Integer ret = -1;
try {
ret = (Integer) new RaspberryTCPClient(myPi, getResources(), RaspberryTCPClient.TYPE_ADD_ROOM, roomName, XMLRoom.TYPE_KITCHEN_ROOM).execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if (ret == RaspberryTCPClient.OPERATION_DONE) {
showToastMessage(getString(R.string.roomAdded));
Intent data = new Intent();
data.putExtra(KEY_ROOM, roomName);
setResult(Activity.RESULT_OK, data);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
}, 1500);
} else {
showToastMessage(getString(R.string.addRoomError));
}
}
private class TypeAdapter extends RecyclerView.Adapter<AddRoomActivity.TypeAdapter.ViewHolder> {
private String[] myData;
public TypeAdapter(String[] roomList) {
myData = roomList;
}
public void onItemClick(int position) {
}
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView tvType;
public CardView cvRoomCard;
public ImageView imgRoomType;
public ViewHolder(View vCard) {
super(vCard);
cvRoomCard = (CardView) vCard;
tvType = (TextView) vCard.findViewById(R.id.tvTypeName);
imgRoomType = (ImageView) vCard.findViewById(R.id.img_roomType);
}
}
#Override
public AddRoomActivity.TypeAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.type_room_recycler_view, parent, false);
// set the view's size, margins, paddings and layout parameters
//...
AddRoomActivity.TypeAdapter.ViewHolder vh = new AddRoomActivity.TypeAdapter.ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(AddRoomActivity.TypeAdapter.ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.tvType.setText(myData[position]);
switch (position) {
case XMLRoom.TYPE_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_room_sqr);
break;
case XMLRoom.TYPE_BED_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_bedroom_sqr);
break;
case XMLRoom.TYPE_GARDEN_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_garden_sqr);
break;
case XMLRoom.TYPE_KITCHEN_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_kitchen_sqr);
break;
case XMLRoom.TYPE_LIVING_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_living_room_sqr);
break;
case XMLRoom.TYPE_SWIMMING_POOL_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_swimming_pool_sqr);
break;
}
holder.cvRoomCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClick(position);
}
});
}
#Override
public int getItemCount() {
return myData.length;
}
}
The MainLayout
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="90dp"
android:layout_marginTop="#dimen/toolbar"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true">
<TextView
android:id="#+id/tvAddRoom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_margin="5dp"
android:gravity="center"
android:text="#string/textAddRoom"
android:textColor="#color/primary_text"
android:textSize="20dp"
android:textStyle="bold" />
<android.support.design.widget.TextInputLayout
android:id="#+id/inputaddRoomName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/tvAddRoom"
android:layout_gravity="center"
android:layout_margin="5dp">
<EditText
android:id="#+id/addRoomName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/prompt_RoomName"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerTypeRoom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/inputaddRoomName"
android:scrollbars="vertical" />
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/doneAddRoom"
android:layout_width="#dimen/fab_Dimension"
android:layout_height="#dimen/fab_Dimension"
android:layout_gravity="bottom|center"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#drawable/ic_done" />
</android.support.design.widget.CoordinatorLayout>
and The View Layout:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp">
<ImageView
android:id="#+id/img_roomType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:src="#drawable/img_room" />
<TextView
android:id="#+id/tvTypeName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="center"
android:textColor="#android:color/white"
android:textSize="20sp" />
</android.support.v7.widget.CardView>
Extracted required info from the accepted answer in case URL becomes invalid in future and to save time.
GridLayoutManager is used to display the RecyclerView in Grid manner instead of list.
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(mLayoutManager);
Kotlin version:
recyclerView.apply {
layoutManager = GridLayoutManager(this, 2)
}
You can use this code simply
<android.support.v7.widget.RecyclerView
app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="2"/>
With androidX libraries simply do:
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"/>
for Horizontal recycler view, it works for me
layoutManagerSuperCategories = new GridLayoutManager(context,2,LinearLayoutManager.HORIZONTAL,false);
rv_superCategories.setLayoutManager(layoutManagerSuperCategories);
use "0dp" in layout_width and layout_height for putting views in it's position.
like this:
android:layout_width="0dp"
and use Guidelines in your xml.
<ImageView
android:id="#+id/img_roomType"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:src="#drawable/img_room" />
<TextView
android:id="#+id/tvTypeName"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:gravity="center"
android:textColor="#android:color/white"
android:textSize="20sp" />
this is NOT true code, u have to use Guidelines.