I encountered a problem while retrieving specific data from the firebase database, however, I was able to retrieve other data and view it using RecyclerView. The address and contact number is not showing. Here is my code and snippet of the output.
lopdetails_items.xml
Emulator Output
LopDetailsAdapter.java
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
public class LoPdetailsAdapter extends
FirebaseRecyclerAdapter<RegisterParking,LoPdetailsAdapter.myViewHolder> {
/**
* Initialize a {#link RecyclerView.Adapter} that listens to a Firebase query. See
* {#link FirebaseRecyclerOptions} for configuration options.
*
* #param options
*/
public LoPdetailsAdapter(#NonNull FirebaseRecyclerOptions<RegisterParking> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull LoPdetailsAdapter.myViewHolder holder, int position, #NonNull RegisterParking model) {
holder.loparkingname.setText(model.getLoparkingname());
holder.lofullname.setText(model.getLofullname());
holder.lorates.setText(model.getLorates());
holder.lovtypes.setText(model.getLovtypes());
holder.loallowed.setText(model.getLoallowed());
holder.loparkingtype.setText(model.getLoparkingtype());
holder.lopenalty.setText(model.getLopenalty());
holder.lonumber.setText(model.getLonumber());
holder.loaddress.setText(model.getLoaddress());
}
#NonNull
#Override
public LoPdetailsAdapter.myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.lopdetails_items,parent,false);
return new LoPdetailsAdapter.myViewHolder(view);
}
class myViewHolder extends RecyclerView.ViewHolder{
TextView loparkingname, lofullname, lorates, lovtypes, loallowed, loparkingtype, lopenalty, lonumber, loaddress;
public myViewHolder(#NonNull View itemView) {
super(itemView);
loparkingname = (TextView) itemView.findViewById(R.id.Pname);
lofullname = (TextView) itemView.findViewById(R.id.fullNamelo);
lonumber = (TextView) itemView.findViewById(R.id.contactnoLO);
loaddress = (TextView) itemView.findViewById(R.id.randomAddress);
lorates = (TextView) itemView.findViewById(R.id.Ratelo);
lovtypes = (TextView) itemView.findViewById(R.id.Typeslo);
loallowed = (TextView) itemView.findViewById(R.id.Numberlo);
loparkingtype = (TextView) itemView.findViewById(R.id.Ptypeslo);
lopenalty = (TextView) itemView.findViewById(R.id.PRateslo);
}
}
}
LoParkingDetails.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.FirebaseDatabase;
public class LoParkingDetails extends AppCompatActivity {
Toolbar toolbar;
private FirebaseAuth mAuth;
//parkingDetails
RecyclerView recyclerView;
LoPdetailsAdapter loPdetailsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lo_parking_details);
toolbar =(Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mAuth = FirebaseAuth.getInstance();
//ParkingDetails
recyclerView = (RecyclerView) findViewById(R.id.loD);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerOptions<RegisterParking> options =
new FirebaseRecyclerOptions.Builder<RegisterParking>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("RegParkingArea"), RegisterParking.class)
.build();
loPdetailsAdapter = new LoPdetailsAdapter(options);
recyclerView.setAdapter(loPdetailsAdapter);
}
//ParkingDetails
#Override
protected void onStart() {
super.onStart();
loPdetailsAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
loPdetailsAdapter.stopListening();
}
//Endpoint
lopdetails_items.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="6dp"
android:elevation="6dp"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="412dp"
android:layout_height="360dp"
android:padding="15dp">
<TextView
android:id="#+id/Pname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Parking Name:"
android:textSize="25dp"
android:textStyle="bold" />
<TextView
android:id="#+id/fullNamelo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/Pname"
android:text="Landowner Fullname:"
android:textSize="25dp" />
<TextView
android:id="#+id/contactnoLO"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/fullNamelo"
android:text="Phone Number:"
android:textSize="25dp" />
<TextView
android:id="#+id/randomAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/contactnoLO"
android:text="Complete Address:"
android:textSize="25dp" />
<TextView
android:id="#+id/Ratelo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/randomAddress"
android:text="Parking Rates:"
android:textSize="25dp" />
<TextView
android:id="#+id/Typeslo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/Ratelo"
android:text="Types of vehicle allowed:"
android:textSize="25dp" />
<TextView
android:id="#+id/Numberlo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/Typeslo"
android:text="Number of allowed Vehicle:"
android:textSize="25dp" />
<TextView
android:id="#+id/Ptypeslo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/Numberlo"
android:text="Type Parking type:"
android:textSize="25dp" />
<TextView
android:id="#+id/PRateslo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/Ptypeslo"
android:text="Penalty Rates:"
android:textSize="25dp" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
Related
I have a NewsDetailsActivity file that is displaying some news details. On top of the news details I want to display some cardview in a recyclerview. The recyclerView is not showing up but the worse part is that another recyclerview (that I have in the MainActivity is showing up in my NewsDetailsActivity like if If I am calling some id from my NewsDetailsActivity.
The only thing I want is to display some information on the top of the news details using the the recyclerview id my_recycler_view_coin_details
NewsDetailsActivity
package com.noticripto.activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.noticripto.APIClientCoin;
import com.noticripto.adapters.CryptoListAdapter;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.noticripto.MainActivity;
import com.noticripto.R;
import com.noticripto.adapters.NewsAdapter;
import com.noticripto.model.HomePageModel;
import com.noticripto.rest.ApiClient;
import com.noticripto.rest.ApiInterface;
import com.noticripto.retrofit.CryptoList;
import com.noticripto.retrofit.Datum;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class NewsDetailActivity extends AppCompatActivity {
Toolbar toolbar;
TextView sourceName, newsTitle, newsDesc, newsDate, newsView,labelSimilar;
Button viewMore;
ImageView imagy,small_icn;
ProgressBar progressBar;
RecyclerView recyclerView3;
CryptoListAdapter adapterCoin2;
ApiInterface apiInterfaceCoin2;
List<Datum> cryptoList2 = null;
HomePageModel.News detailNews = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news_detail);
apiInterfaceCoin2 = APIClientCoin.getClient().create(ApiInterface.class);
recyclerView3 = findViewById(R.id.my_recycler_view_coin_details);
initViews();
LoadNewsDetails();
getCoinList();
}
private void LoadNewsDetails() {
// Calling our api
ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Map<String, String> params = new HashMap<>();
params.put("id" , getIntent().getIntExtra("pid", 0) + "");
Call<HomePageModel> call = apiInterface.getNewsDetailsById(params);
call.enqueue(new Callback<HomePageModel>() {
#Override
public void onResponse(Call<HomePageModel> call, Response<HomePageModel> response) {
// Update the news layout
detailNews = response.body().getNews().get(0);
newsTitle.setText(detailNews.getTitle());
newsDesc.setText(NewsAdapter.removeHtml(detailNews.getPostContent()));
if (detailNews.getImage().length() >=1){
Glide.with(NewsDetailActivity.this)
.load(detailNews.getImage())
.placeholder(R.drawable.image1)
.into(imagy);
}else{
imagy.setVisibility(View.GONE);
}
}
#Override
public void onFailure(Call<HomePageModel> call, Throwable t) {
progressBar.setVisibility(View.GONE);
}
});
}
private void initViews() {
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
toolbar.setNavigationIcon(R.drawable.icon_arrow_back_white);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
cryptoList2 = new ArrayList<>();
adapterCoin2 = new CryptoListAdapter(cryptoList2);
// sourceName = findViewById(R.id.source_name );
newsTitle = findViewById(R.id.news_title);
newsDesc = findViewById(R.id.news_desc);
newsDate = findViewById(R.id.news_date);
//newsView = findViewById(R.id.news_view);
labelSimilar = findViewById(R.id.label_similar_news);
//viewMore = findViewById(R.id.view_more);
progressBar = findViewById(R.id.progressBar);
imagy =findViewById(R.id.news_image);
//small_icn = findViewById(R.id.small_icn);
recyclerView3 = findViewById(R.id.my_recycler_view_coin_details);
LinearLayoutManager linearLayoutManager3 =new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
recyclerView3.setLayoutManager(linearLayoutManager3);
recyclerView3.setNestedScrollingEnabled(false);
recyclerView3.setAdapter(adapterCoin2);
adapterCoin2.notifyItemInserted(0);
recyclerView3.scrollToPosition(0);
}
public void getCoinList() {
Call<CryptoList> call2 = apiInterfaceCoin2.doGetUserList("20");
call2.enqueue(new Callback<CryptoList>() {
#Override
public void onResponse(Call<CryptoList> call, Response<CryptoList> response)
{
CryptoList list = response.body();
cryptoList2.clear();
cryptoList2.addAll(list.getData());
adapterCoin2.notifyDataSetChanged();
System.out.println("List getData = " + list.getData());
}
#Override
public void onFailure(Call<CryptoList> call, Throwable t) {
Toast.makeText(NewsDetailActivity.this, "onFailure",
Toast.LENGTH_SHORT).show();
Log.d("XXXX", t.getLocalizedMessage());
call.cancel();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.news_details_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.share){
if (detailNews != null){
// Opening sharing options
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, detailNews.getTitle());
i.putExtra(Intent.EXTRA_TEXT, detailNews.getPostContent());
startActivity(i);
}else{
Toast.makeText(this, "Lo Sentimos!", Toast.LENGTH_SHORT).show();
}
}
return super.onOptionsItemSelected(item);
}
}
crypto_list_item_in_detail_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardViewCoinDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="3dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
app:cardCornerRadius="8dp"
app:cardBackgroundColor="#android:color/white">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/symbolNameDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="roboto_bold"
android:gravity="center"
android:paddingBottom="3dp"
android:singleLine="true"
android:text="Symbol"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#000"
android:textSize="15dp" />
<TextView
android:id="#+id/priceDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textStyle="bold"
android:text="Price"
android:textSize="13dp"
android:layout_marginBottom="5dp"
android:layout_toRightOf="#+id/symbolNameDetails"
android:textAppearance="#android:style/TextAppearance.Medium"
android:textColor="#000" />
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
activity_news_details.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=".activities.NewsDetailActivity">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/toolbar"
android:background="#color/black"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_below="#+id/toolbar"
android:layout_height="wrap_content">
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:indeterminateTint="#color/yellow"/>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:overScrollMode="never"
android:layout_below="#+id/progressBar">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/my_recycler_view_coin_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="horizontal" />
<androidx.cardview.widget.CardView
android:id="#+id/wrapper_cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/news_title"
android:text="Titulo"
android:textStyle="bold"
android:layout_below="#+id/wrapper"
android:textSize="22sp"
android:paddingLeft="16dp"
android:textAlignment="center"
android:paddingStart="16dp"
android:textColor="#color/black"
android:gravity="center_horizontal" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/wrapper_news"
android:layout_below="#id/news_title"
android:paddingLeft="10dp"
android:layout_marginTop="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/news_date"
android:paddingEnd="10dp"
android:paddingStart="10dp"
android:text="Date"
android:paddingRight="5dp"/>
</RelativeLayout>
<ImageView
android:layout_width="match_parent"
android:adjustViewBounds="true"
android:id="#+id/news_image"
android:src="#drawable/icon_youtube"
android:layout_below="#id/wrapper_news"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/news_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/news_image"
android:fontFamily="#font/roboto"
android:padding="10dp"
android:text="News Description"
android:firstBaselineToTopHeight="0dp"
android:includeFontPadding="false"
android:lineSpacingExtra="2dp"
android:textColor="#color/black"
android:textSize="17sp" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/wrapper_cardview"
android:padding="10dp"
android:textSize="18sp"
android:text="Similar News"
android:visibility="gone"
android:id="#+id/label_similar_news"/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/news_recy"
android:layout_below="#id/label_similar_news"/>
</RelativeLayout>
</androidx.core.widget.NestedScrollView>
</RelativeLayout>
</RelativeLayout>
And finally, I am trying to get the list from here:
CryptoListAdapter
package com.noticripto.adapters;
import android.content.Context;
import android.graphics.Color;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.noticripto.retrofit.Datum;
import com.noticripto.R;
import java.util.List;
public class CryptoListAdapter extends
RecyclerView.Adapter<CryptoListAdapter.ViewHolder> {
private List<Datum> mData;
private ItemClickListener mClickListener;
ImageView arrowImage;
RelativeLayout layout;
RelativeLayout symbolBG;
// data is passed into the constructor
public CryptoListAdapter(List<Datum> data) {
this.mData = data;
}
// Usually involves inflating a layout from XML and returning the holder
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.crypto_list_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
layout = view.findViewById(R.id.relativeBG);
symbolBG = view.findViewById(R.id.symbolBG);
arrowImage = view.findViewById(R.id.arrow_img);
return viewHolder;
}
// Involves populating data into the item through holder
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Get the data model based on position
Datum datum = mData.get(position);
TextView symbolName = holder.symbolName;
symbolName.setText(" (" + datum.getSymbol() + ")");
// Set item views based on your views and data model
TextView name = holder.name;
name.setText(datum.getName());
TextView symbolNameDetails = holder.symbolNameDetails;
symbolNameDetails.setText(datum.getSymbol());
TextView price = holder.price;
TextView priceDetails = holder.priceDetails;
if(datum.getQuote().getUSD().getPrice() >= 1) {
price.setText("$" + String.format("%.2f", datum.getQuote().getUSD().getPrice()));
priceDetails.setText("$" + String.format("%.2f", datum.getQuote().getUSD().getPrice()));
}else{
price.setText("$" + String.format("%f", datum.getQuote().getUSD().getPrice()));
priceDetails.setText("$" + String.format("%.2f", datum.getQuote().getUSD().getPrice()));
}
//TextView marketCap = holder.marketCap;
//marketCap.setText("Market Cap: $" + String.format("%,d",
Math.round(datum.getQuote().getUSD().getMarketCap())));
//TextView volume24h = holder.volume24h;
//volume24h.setText("Volume/24h: $" + String.format("%,d",
Math.round(datum.getQuote().getUSD().getVolume24h())));
//TextView textView1h = holder.textView1h;
//textView1h.setText(String.format("1h: %.2f",
datum.getQuote().getUSD().getPercentChange1h()) + "%");
TextView textView24h = holder.textView24h;
textView24h.setText(String.format("%.2f", datum.getQuote().getUSD().getPercentChange24h()) + "%");
if(datum.getQuote().getUSD().getPercentChange24h() < 0.0){
//red
textView24h.setText(String.format("%.2f", Math.abs(datum.getQuote().getUSD().getPercentChange24h())) + "%");
textView24h.setTextColor(Color.parseColor("#ffffff"));
arrowImage.setImageResource(R.drawable.arrow_down_white);
layout.setBackgroundColor(Color.parseColor("#EA3943"));
symbolBG.setBackgroundColor(Color.parseColor("#EA3943"));
priceDetails.setTextColor(Color.parseColor("#EA3943"));
}else{
//green
textView24h.setText(String.format("%.2f",
Math.abs(datum.getQuote().getUSD().getPercentChange24h())) + "%");
textView24h.setTextColor(Color.parseColor("#ffffff"));
arrowImage.setImageResource(R.drawable.arrow_up_white);
layout.setBackgroundColor(Color.parseColor("#18C784"));
symbolBG.setBackgroundColor(Color.parseColor("#18C784"));
priceDetails.setTextColor(Color.parseColor("#18C784"));
}
//TextView textView7d = holder.textView7d;
//textView7d.setText(String.format("7d: %.2f",
datum.getQuote().getUSD().getPercentChange7d()) + "%");
}
// Returns the total count of items in the list
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// Provide a direct reference to each of the views within a data item
// Used to cache the views within the item layout for fast access
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
// Your holder should contain a member variable
// for any view that will be set as you render a row
TextView name;
TextView price;
TextView marketCap;
TextView volume24h;
TextView textView1h;
TextView textView24h;
TextView textView7d;
TextView symbolName;
TextView priceDetails;
TextView symbolNameDetails;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
ViewHolder(View itemView) {
// Stores the itemView in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(itemView);
name = itemView.findViewById(R.id.name);
price = itemView.findViewById(R.id.price);
//marketCap = itemView.findViewById(R.id.marketCap);
// volume24h = itemView.findViewById(R.id.volume24h);
//textView1h = itemView.findViewById(R.id.textView1h);
textView24h = itemView.findViewById(R.id.textView24h);
//textView7d = itemView.findViewById(R.id.textView7d);
symbolName = itemView.findViewById(R.id.symbolName);
priceDetails = itemView.findViewById(R.id.priceDetails);
symbolNameDetails = itemView.findViewById(R.id.symbolNameDetails);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view,
getAdapterPosition());
}
}
// convenience method for getting data at click position
public Datum getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
The log doesn't say anything helpful just that the list might be empty but the same list is working on the MainActivity so, I believe the problem is inside my NewsDetailActivity.
I also tried some of the answers and none of them helped me:
RecyclerView is not showing
RecyclerView is not showing items
CardView is not showing properly in RecyclerView
Again, i just want to display my list from CryptoListAdapter under the NewsDetailActivity toolbar...in a nice cardview
This is what I want to do...
this is simple and normal! you fill your array in getCoinList() but set adapter for RecyclerView in initViews() in this way your array not filled yet but you pass it to your recycler! , you should get your array first , then pass it to adapter and set adapter to RecyclerView.
So here is my problem, I got an API that gives me the lastest news of many sources. Each one of them goes with a cardview. The problem here is, while I'm using the swipeRefresh, it gets duplicated cardViews with the same news, like if I have 10 news, it duplicates to 20 with the same ones.
Here is my code where I apply the swipeRefresh:
package com.example.newsapp4;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.newsapp4.Model.Articles;
import com.example.newsapp4.Model.Headlines;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class bbcnews extends AppCompatActivity {
Adapter adapter;
Intent intencion;
RecyclerView recyclerView;
public static String source = "My Source";
public static String API_KEY = "My API Key";
SwipeRefreshLayout srl;
List<Articles> articles = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bbcnews);
srl = findViewById(R.id.swipeRefresh);
srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
retrieveJson(source, API_KEY);
}
});
recyclerView = findViewById(R.id.recyclerView1);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new Adapter(bbcnews.this,articles);
recyclerView.setAdapter(adapter);
retrieveJson(source, API_KEY);
}
public void retrieveJson(String source, String apiKey){
srl.setRefreshing(true);
Call<Headlines> call = ApiClient.getInstance().getApi().getHeadlines(source, apiKey);
call.enqueue(new Callback<Headlines>() {
#Override
public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if(response.isSuccessful() && response.body().getArticles() != null){
srl.setRefreshing(false);
articles.clear();
articles = response.body().getArticles();
adapter.setArticles(articles);
}
}
#Override
public void onFailure(Call<Headlines> call, Throwable t) {
srl.setRefreshing(false);
Toast.makeText(bbcnews.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String getCountry(){
Locale locale = Locale.getDefault();
String country = locale.getCountry();
return country.toLowerCase();
}
public void aPerfil(View vista){
intencion = new Intent(this, profile_activity.class);
startActivity(intencion);
}
}
I don't think that I need to put the xml code with the progressbar and the swipeRefresh but here are both:
This one is the Items.xml where I created the cardView:
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:cardElevation="4dp"
android:id="#+id/cardView"
app:cardCornerRadius="10dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#+id/loader"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/image"
android:scaleType="centerCrop"
android:src="#drawable/img"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/gradient" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TITLE"
android:textSize="20dp"
android:padding="10dp"
android:fontFamily="#font/g_bold"
android:textColor="#color/white"
android:id="#+id/tvTitle"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Source"
android:textSize="16dp"
android:padding="10dp"
android:ems="15"
android:fontFamily="#font/g_light"
android:textColor="#color/white"
android:id="#+id/tvSource"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/g_light"
android:gravity="right"
android:text="Date"
android:textColor="#color/white"
android:padding="10dp"
android:textSize="16dp"
android:id="#+id/tvDate"/>
</LinearLayout>
</FrameLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
And here the one with the swipeRefresh in the recyclerView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/white"
tools:context=".bbcnews">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="DINGO BBC NEWS"
android:textColor="#color/black"
android:textSize="20sp"
android:fontFamily="#font/g_bold"
android:background="#color/white"
android:padding="10dp"
android:textAlignment="center"/>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:columnCount="2"
android:paddingLeft="20dp"
android:paddingRight="5dp"
android:background="#drawable/black_background"
android:rowCount="2">
<EditText
android:id="#+id/editTextTextPersonName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Search"
android:textColor="#color/grey"
android:textColorHint="#color/grey"
android:padding="5dp"
android:layout_column="0"
android:background="#drawable/black_background"
android:layout_row="0"
android:layout_columnWeight="1"
android:inputType="textPersonName" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="20dp"
android:background="#drawable/black_background"
android:drawableRight="#drawable/ic_baseline_search_24"
android:layout_column="1"
android:layout_row="0"/>
</GridLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipeRefresh">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:id="#+id/recyclerView1"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
Also this is my adapter.java code:
package com.example.newsapp4;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.newsapp4.Model.Articles;
import com.squareup.picasso.Picasso;
import java.util.List;
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
Context context;
List<Articles> articles;
public Adapter(Context context, List<Articles> articles) {
this.context = context;
this.articles = articles;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Articles a = articles.get(position);
String imageUrl = a.getUrlToImage();
holder.tvTitle.setText(a.getTitle());
holder.tvSource.setText(a.getSource().getName());
holder.tvDate.setText(a.getPublishedAt());
Picasso.with(context).load(imageUrl).into(holder.imageView);
}
#Override
public int getItemCount() {
return articles.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle,tvSource,tvDate;
ImageView imageView;
CardView cardView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvSource = itemView.findViewById(R.id.tvSource);
tvDate = itemView.findViewById(R.id.tvDate);
imageView = itemView.findViewById(R.id.image);
cardView = itemView.findViewById(R.id.cardView);
}
}
public void setArticles(List<Articles> articles) {
this.articles.addAll(articles);
int count = getItemCount();
notifyItemRangeInserted(count, count + articles.size());
}
}
Thanks for your time!
// Clear adapter list before add to list.
public void setArticles(List<Articles> articles) {
if(this.articles!=null && this.articles.size()>0)
this.articles.clear();
this.articles.addAll(articles);
int count = getItemCount();
notifyItemRangeInserted(count, count + articles.size());
}
From what I can understand in your code is on the success of API call after Swipe Refresh which is this section here
articles.clear();
articles = response.body().getArticles();
adapter.setArticles(articles);
You are here clearing the article inside your activity, but the thing is inside your Adapter there is already another list of articles, you are not clearing them.
And then when you make the adapter.setArticles(articles); call, inside the following function, your articles get added to the already existing list of articles and thus, the duplicate list.
public void setArticles(List<Articles> articles) {
this.articles.addAll(articles);
int count = getItemCount();
notifyItemRangeInserted(count, count + articles.size());
}
To fix this you can make the following modifications to your function.
public void setArticles(List<Articles> articles, boolean clearAll) {
if(clearAll){ this.articles.clear(); }
this.articles.addAll(articles);
notifyDataSetChanged();
}
And then modify your function call as follows
adapter.setArticles(articles, true);
That way when the Boolean is true, it will clear the existing list. Also I would suggest you to replace the insert call with data set change call. Else you can make a separate function all together for adding elements and for clearing existing elements.
I'm looking to implement a search function. When it runs, logcat is telling me:
E/RecyclerView: No adapter attached; skipping layout.
I have searched SO and the net and the answers tell me that I need to set the adapter and the linear layout manager. As you will see with my code, I set both. Alex Mamo's (#AlexMamo) work on here seems to point me in the right direction but I'm still getting the error.
My Activity
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.MyApp.Objects.ParticipantsObject;
import com.MyApp.R;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
public class ParticipantsActivity extends AppCompatActivity {
private EditText mSearchField;
private ImageButton mSearchBtn;
private RecyclerView mResultList;
private DatabaseReference mUserDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_neighbors);
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child("Participants");
mSearchField = (EditText) findViewById(R.id.search_field);
mSearchBtn = (ImageButton) findViewById(R.id.search_btn);
mResultList = (RecyclerView) findViewById(R.id.result_list);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
mSearchBtn.setOnClickListener(view -> {
String searchText = mSearchField.getText().toString();
firebaseUserSearch(searchText);
});
}
private void firebaseUserSearch(String searchText) {
Toast.makeText(ParticipantsActivity.this, "Started Search", Toast.LENGTH_LONG).show();
Query firebaseSearchQuery = mUserDatabase.orderByChild("name").startAt(searchText);
FirebaseRecyclerOptions<ParticipantsObject> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<ParticipantsObject>()
.setQuery(firebaseSearchQuery, ParticipantsObject.class)
.build();
class UserHolder extends RecyclerView.ViewHolder {
private TextView imageThumbTextView, nameTextView
UserHolder(View itemView) {
super(itemView);
imageThumbTextView = itemView.findViewById(R.id.profile_image);
nameTextView = itemView.findViewById(R.id.name_text);
}
void setUsers(ParticipantsObject participantsObject) {
String imageThumb = driverObject.getThumb_image();
imageThumbTextView.setText(imageThumb);
String name = participantsObject.getName();
nameTextView.setText(name);
}
}
FirebaseRecyclerAdapter<ParticipantsObject, UserHolder> firebaseRecyclerAdapter;
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ParticipantsObject, UserHolder>(firebaseRecyclerOptions) {
#Override
protected void onBindViewHolder(#NonNull UserHolder userHolder, int position, #NonNull ParticipantsObject participantsObject) {
userHolder.setUsers(participantsObject);
}
#Override
public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout, parent, false);
return new UserHolder(view);
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.startListening();
}
}
My Activity XML file
<?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"
android:background="#ffffff"
tools:context="com.MyApp.ParticipantsActivity">
<TextView
android:id="#+id/heading_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="30dp"
android:text="Firebase Search"
android:textColor="#555555"
android:textSize="24sp" />
<EditText
android:id="#+id/search_field"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/heading_label"
android:layout_below="#+id/heading_label"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:layout_toStartOf="#+id/search_btn"
android:background="#drawable/search_layout"
android:ems="10"
android:hint="Search here"
android:inputType="textPersonName"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:textColor="#999999"
android:textSize="16sp" />
<ImageButton
android:id="#+id/search_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/search_field"
android:layout_alignParentEnd="true"
android:layout_alignTop="#+id/search_field"
android:layout_marginRight="30dp"
android:background="#android:color/background_light"
app:srcCompat="#mipmap/search_button" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/result_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/search_field"
android:layout_marginTop="50dp">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
My list layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/profile_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="20dp"
app:srcCompat="#mipmap/ic_default_user" />
<TextView
android:id="#+id/name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="14dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="213dp"
android:layout_marginRight="20dp"
android:layout_toEndOf="#+id/profile_image"
android:text="Username"
android:textColor="#555555"
android:textSize="16sp" />
</RelativeLayout>
Any ideas or advice would be much appreciated.
Your code is setting the adapter only after a button is pushed. Because you didn't set it before the first time the RecyclerView needed to render itself on screen, it's going to warn you about that with the message you see in the log. The RecyclerView must have an adapter attached at the time of rendering in order for it to display anything.
I created a page where it will show the firebase data in a RecyclerView. It work but I decided to put a toolbar at the top of the page to have a back function. After I put the toolbar in my layout file, the RecyclerView is not showing any data anymore. I think that my layout XML file is wrong. Thanks in advance for anyone helping.
Actity file
package com.example.attendanceappvqyfyp;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import com.example.attendanceappvqyfyp.Interface.itemClickListener;
import com.example.attendanceappvqyfyp.Common.Common;
import com.example.attendanceappvqyfyp.Model.LecturerClass;
import com.example.attendanceappvqyfyp.Model.News;
import com.example.attendanceappvqyfyp.Model.Timetable;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.example.attendanceappvqyfyp.Common.Common;
public class LecturerClassList extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
FirebaseDatabase database;
DatabaseReference lecturerclass;
DatabaseReference news;
FirebaseRecyclerAdapter<LecturerClass,LecturerClassViewHolder> adapter;
TextView newscourse, newsclass;
EditText newsdescription;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lecturer_class_list);
//Firebase
database = FirebaseDatabase.getInstance();
lecturerclass = database.getReference("Class");
news = database.getReference("News");
recyclerView = (RecyclerView)findViewById(R.id.recycler_lecturerclass);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//Toolbar code
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle("Class List");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back_black_24dp);
loadLecturerClass(Common.currentLecturer.getName());
}
private void loadLecturerClass(String Lecturer) {
adapter = new FirebaseRecyclerAdapter<LecturerClass, LecturerClassViewHolder>(LecturerClass.class, R.layout.lecturerclass_item, LecturerClassViewHolder.class, lecturerclass.orderByChild("lecturer").equalTo(Lecturer)) {
#Override
protected void populateViewHolder(LecturerClassViewHolder lecturerClassViewHolder, LecturerClass lecturerClass, int i) {
lecturerClassViewHolder.lclasstitle.setText("Class :" + adapter.getRef(i).getKey());
lecturerClassViewHolder.ldate.setText("Day :" + lecturerClass.getDay());
lecturerClassViewHolder.ltime.setText("Time :" + lecturerClass.getTime());
lecturerClassViewHolder.lclassroom.setText("Classroom :" + lecturerClass.getClassroom());
lecturerClassViewHolder.lcourse.setText(lecturerClass.getCourse());
lecturerClassViewHolder.setItemClickListener(new itemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
//code later
}
});
}
};
recyclerView.setAdapter(adapter);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
if(item.getTitle().equals(Common.News))
{
showNewsDialog(adapter.getRef(item.getOrder()).getKey(),adapter.getItem(item.getOrder()));
}
return super.onContextItemSelected(item);
}
private void showNewsDialog(final String course, final LecturerClass item) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(LecturerClassList.this);
alertDialog.setTitle("Make Announcement");
alertDialog.setMessage("Make announcement about this class.");
LayoutInflater inflater = this.getLayoutInflater();
View lecturer_make_news = inflater.inflate(R.layout.activity_lecturer_make_news, null);
newscourse = lecturer_make_news.findViewById(R.id.NewsCourse);
newsclass = lecturer_make_news.findViewById(R.id.NewsClass);
newsdescription = lecturer_make_news.findViewById(R.id.NewsDescription);
newscourse.setText("Course: "+item.getCourse());
newsclass.setText("Subject: " + course);
alertDialog.setView(lecturer_make_news);
alertDialog.setPositiveButton("Post", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int i) {
if(newsdescription.getText().toString().isEmpty()){
Toast.makeText(LecturerClassList.this, "Post cancel, description cannot be empty.", Toast.LENGTH_SHORT).show();
}
else {
News lnews = new News(
item.getCourse(),
course,
newsdescription.getText().toString()
);
news.child(String.valueOf(System.currentTimeMillis())).setValue(lnews);
Toast.makeText(LecturerClassList.this, "Announcement post successfully.", Toast.LENGTH_SHORT).show();
finish();
}
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();;
}
});
alertDialog.show();
}
}
Activity file for viewholder
package com.example.attendanceappvqyfyp;
import android.view.ContextMenu;
import android.view.View;
import android.widget.TextView;
import com.example.attendanceappvqyfyp.Common.Common;
import androidx.recyclerview.widget.RecyclerView;
import com.example.attendanceappvqyfyp.Interface.itemClickListener;
public class LecturerClassViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnCreateContextMenuListener {
public TextView lclasstitle, ldate, ltime, lclassroom, lcourse;
private itemClickListener itemClickListener;
public LecturerClassViewHolder(View itemView) {
super(itemView);
lclasstitle = (TextView)itemView.findViewById(R.id.lclasstitle);
ldate = (TextView)itemView.findViewById(R.id.ldate);
ltime = (TextView)itemView.findViewById(R.id.ltime);
lclassroom = (TextView)itemView.findViewById(R.id.lclassroom);
lcourse = (TextView)itemView.findViewById(R.id.lcourse);
itemView.setOnCreateContextMenuListener(this);
itemView.setOnClickListener(this);
}
public void setItemClickListener(itemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public void onClick(View view) {
itemClickListener.onClick(view, getAdapterPosition(), false);
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select");
menu.add(0,0,getAdapterPosition(), Common.News);
}
}
Layout file for recyclerview
<?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"
tools:context=".LecturerClassList">
<android.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:theme="#style/ThemeOverlay.AppCompat.Dark" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_lecturerclass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layout_constraintTop_toBottomOf="#+id/toolbar" />
</androidx.constraintlayout.widget.ConstraintLayout>
Layout file for itemview
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="160dp"
app:cardElevation="4dp"
android:layout_marginBottom="8dp"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/lclasstitle"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:text=""
android:textColor="#android:color/black"
android:textSize="20sp" />
<TextView
android:id="#+id/ldate"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignBottom="#id/lclasstitle"
android:layout_marginBottom="-40dp"
android:gravity="center"
android:text=""
android:textColor="#android:color/black"
android:textSize="20sp" />
<TextView
android:id="#+id/ltime"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignBottom="#id/ldate"
android:layout_marginBottom="-40dp"
android:gravity="center"
android:text=""
android:textColor="#android:color/black"
android:textSize="20sp" />
<TextView
android:id="#+id/lclassroom"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text=""
android:textColor="#android:color/black"
android:textSize="20sp" />
<TextView
android:id="#+id/lcourse"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text=""
android:visibility="invisible"
android:textColor="#android:color/black"
android:textSize="20sp" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
Thanks to ZeePee for giving this link Display Back Arrow on Toolbar, although the toolbar didnt work for me, i change it back to actionbar and use the code from the link and it work.
Try adding horizontal constraints for Toolbar and Recycler View. After that you need to specify where do you want your single item widgets in Relative layout
In my project I want the search activity to display two types of data in the search activity (restaurants and meals) and I want to implement it like in Twitter and Instagram, my approach is as follows:
in the search activity I created two fragments with each one having a simple list view, my data gets displayed when launching the app but list views don't display all the items at ones, instead, it makes them scroll (in Instagram search activity it shows the suggested and recent items with full height)
this is the code
search activity:
package com.byshy.light.Activities;
import android.content.pm.ActivityInfo;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.WindowManager;
import com.byshy.light.Fragments.SearchRestaurantsFragment;
import com.byshy.light.R;
import com.byshy.light.SearchMealsFragment;
public class SearchActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.search_restaurants_frag, new SearchRestaurantsFragment()).commit();
FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.search_meals_frag, new SearchMealsFragment()).commit();
}
}
search activity xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activities.SearchActivity">
<FrameLayout
android:layout_alignParentTop="true"
android:id="#+id/search_container"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/colorPrimary"
android:transitionName="search_bar">
<EditText
android:id="#+id/main_screen_search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="7dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="7dp"
android:background="#drawable/curved_layout"
android:hint="#string/search"
android:inputType="text"
android:padding="10dp" />
</FrameLayout>
<ScrollView
android:layout_alignParentBottom="true"
android:layout_below="#id/search_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="#+id/search_restaurants_frag"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<FrameLayout
android:id="#+id/search_meals_frag"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
restaurants fragment:
package com.byshy.light.Fragments;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.byshy.light.R;
public class SearchRestaurantsFragment extends Fragment {
ListView lv1;
public SearchRestaurantsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_search_restaurants, container, false);
lv1 = root.findViewById(R.id.search_restaurants_list_view);
String[] items1 = new String[3];
items1[0] = "res1";
items1[1] = "res2";
items1[2] = "res3";
ArrayAdapter<String> aa1 = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, items1);
lv1.setAdapter(aa1);
return root;
}
}
meals fragment:
package com.byshy.light;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class SearchMealsFragment extends Fragment {
ListView lv2;
public SearchMealsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_search_meals, container, false);
lv2 = root.findViewById(R.id.search_meals_list_view);
String[] items2 = new String[10];
items2[0] = "meal1";
items2[1] = "meal2";
items2[2] = "meal3";
items2[3] = "meal4";
items2[4] = "meal5";
items2[5] = "meal6";
items2[6] = "meal7";
items2[7] = "meal8";
items2[8] = "meal9";
items2[9] = "meal10";
ArrayAdapter<String> aa2 = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, items2);
lv2.setAdapter(aa2);
return root;
}
}
the fragments xml is basically the same with some id differences so I will post just one:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SearchMealsFragment">
<RelativeLayout
android:id="#+id/small_search_restaurants_bar"
android:layout_width="match_parent"
android:layout_height="35dp"
android:background="#color/white"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:text="#string/meals"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="10dp"
android:text="#string/more"
android:textColor="#color/colorPrimaryDark"
android:textSize="15sp" />
</RelativeLayout>
<ListView
android:id="#+id/search_meals_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
after not finding anything useful on the internet I came up with a new approach to solve this problem.
my new approach is more efficient and it works by creating a model for search results which contains a string and an integer to indicate if the view is a header or a result, then created a item view that contains a linear layout that gets hidden if the view is a not a header, this logic is done inside the adapter.
this is the code:
this is the search_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:clickable="false"
android:focusable="false"
android:foreground="?android:attr/selectableItemBackground">
<LinearLayout
android:orientation="vertical"
android:id="#+id/search_item_back_bar"
android:layout_width="match_parent"
android:layout_centerVertical="true"
android:background="#color/colorPrimary"
android:layout_height="2dp">
</LinearLayout>
<TextView
android:background="#f9f9f9"
android:layout_marginStart="16dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:id="#+id/search_result"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/test"
android:textSize="20sp" />
</RelativeLayout>
new searchActivity.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=".Activities.SearchActivity">
<FrameLayout
android:id="#+id/search_container"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/colorPrimary"
android:transitionName="search_bar">
<EditText
android:id="#+id/main_screen_search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="7dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="7dp"
android:background="#drawable/curved_layout"
android:hint="#string/search"
android:inputType="text"
android:padding="10dp" />
</FrameLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/search_activity_results"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
searchActivity.java
package com.byshy.light.Activities;
import android.content.pm.ActivityInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.WindowManager;
import com.byshy.light.Adapters.SearchResultsAdapter;
import com.byshy.light.Models.SearchResult;
import com.byshy.light.R;
import java.util.ArrayList;
public class SearchActivity extends AppCompatActivity {
private RecyclerView searchRV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
searchRV = findViewById(R.id.search_activity_results);
searchRV.setHasFixedSize(true);
searchRV.setLayoutManager(new LinearLayoutManager(this));
ArrayList<SearchResult> results = new ArrayList<>();
results.add(new SearchResult("Restaurants", 1));
results.add(new SearchResult("res1"));
results.add(new SearchResult("res2"));
results.add(new SearchResult("res3"));
results.add(new SearchResult("Meals", 1));
results.add(new SearchResult("meal1"));
results.add(new SearchResult("meal2"));
results.add(new SearchResult("meal3"));
results.add(new SearchResult("meal4"));
results.add(new SearchResult("meal5"));
results.add(new SearchResult("meal6"));
SearchResultsAdapter adapter = new SearchResultsAdapter(results);
searchRV.setAdapter(adapter);
}
}
SearchResultsAdapter.java
package com.byshy.light.Adapters;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.byshy.light.Models.SearchResult;
import com.byshy.light.R;
import java.util.ArrayList;
public class SearchResultsAdapter extends RecyclerView.Adapter<SearchResultsAdapter.SearchResultViewHolder> {
private ArrayList<SearchResult> mData;
public SearchResultsAdapter(ArrayList<SearchResult> data) {
mData = data;
}
#NonNull
#Override
public SearchResultViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.search_item, viewGroup, false);
return new SearchResultViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull SearchResultViewHolder searchResultViewHolder, int i) {
SearchResult searchResult = mData.get(i);
searchResultViewHolder.result.setText(searchResult.getContent());
if (searchResult.getType() == 0) {
searchResultViewHolder.backBar.setVisibility(View.GONE);
searchResultViewHolder.setClickable(true);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) searchResultViewHolder.result.getLayoutParams();
params.leftMargin = 8;
}
}
#Override
public int getItemCount() {
return mData.size();
}
class SearchResultViewHolder extends RecyclerView.ViewHolder {
private TextView result;
private LinearLayout backBar;
private View view;
public SearchResultViewHolder(#NonNull View itemView) {
super(itemView);
view = itemView;
result = itemView.findViewById(R.id.search_result);
backBar = itemView.findViewById(R.id.search_item_back_bar);
}
public void setClickable(boolean clickable) {
view.setClickable(clickable);
view.setFocusable(clickable);
}
}
}
the end product