I want to start an activity when i click on one of the item of my RecyclerView. Unfortunately when i click on an item nothing happens and I'm stuck here.
I think the code into the onClick method is right (But maybe I'm wrong). I tried to add a Log.d to see if the listener works but i can't see it in the logcat when i click on an item. I'm new on programming so it can be a stupid error. Thanks for help :)
public class UsersRecyclerAdapter extends RecyclerView.Adapter<UsersRecyclerAdapter.ViewHolder> {
private Context context;
private List<Users> usersList;
public UsersRecyclerAdapter(Context context, List<Users> usersList) {
this.context = context;
this.usersList = usersList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_row, parent, false);
return new ViewHolder(view, context);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Users users = usersList.get(position);
holder.firstName.setText(users.getFirstName());
holder.lastName.setText(users.getLastName());
holder.classe.setText(users.getClasse());
String avatarURL = users.getAvatar();
Picasso.get().load(avatarURL).into(holder.avatar);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("MyApp","I am here");
context = view.getContext();
Intent intent = new Intent(context, PDFPostListActivity.class);
// String userID = users.getUserID();
// intent.putExtra("userID", userID);
context.startActivity(intent);
}
});
}
EDIT. Here is the root view (users_row):
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageViewAVATAR"
android:layout_width="50dp"
android:layout_height="50dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp" />
<TextView
android:id="#+id/textViewfistName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
<TextView
android:id="#+id/textViewlastName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
<TextView
android:id="#+id/textViewclass"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
</LinearLayout>
</HorizontalScrollView>
</androidx.cardview.widget.CardView>
What's the root view of the view holder? Set it to be clickable since you set onClickListener on itemView of view holder.
Great thanks to #Mike M. who rapidly answer in the comment below the question. I paste the message:
When you call setOnClickListener() on itemView, it's setting that on the , since that's the outermost View there. The nested within it is preventing it from receiving click events. Assuming that's all that going to be in that layout, then the simplest fix would probably be to simply set the OnClickListener on the instead. You'll need to give it an android:id, find it with findViewById() just like you did the TextViews, and then call setOnClickListener() on that, instead of itemView.
Related
Good day - I'm new to recyclerViews and connecting to Room database. I've got one working with the help from a tutorial and now I want to add to it. My aim is to:
Implement a Room database which in turn presents data to the user via a recyclerView.
Have 1 recyclerView in the main activity and a 2nd recyclerView in a second activity. I'm trying to have a different layout in each activity as shown in the following links.
Main activity:
Second activity:
The issue I'm having is even though the XML files are unique for each activity, along with the variables within, the name of the recyclerView, and also the methods for each activity, the layout in the second activity shows in the first activity.
activity_main has the following:
<androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="100dp"
android:id="#+id/recycler_view111"
android:layout_width="match_parent"
android:layout_height="114dp"
tools:listitem="#layout/testing" />
The second activity XML file has the following:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="488dp"
tools:listitem="#layout/testing1_item" />
Can someone please help me identify why the same recyclerView is shown across the 2 activities please?
To trouble-shoot, I've:
Gone through all the XML files to ensure there is no issue with the names of the files/methods etc.
Copied the layout from the activity_main xml and applied it to the second xml file. This then in turn displayed the layout that I'm testing within in MainActivity across both activities.
MainActivity uses the activity_main.xml which uses a test file called testing.xml - code as follows:
MainActivity:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(getApplicationContext(), AllWordsActivity.class);
startActivity(intent);
}
});
RecyclerView recyclerView111 = findViewById(R.id.recycler_view111);
recyclerView111.setLayoutManager(new LinearLayoutManager(this));
recyclerView111.setHasFixedSize(true);
NoteAdapter adapter = new NoteAdapter();
recyclerView111.setAdapter(adapter);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>()
{
#Override
public void onChanged(List<Note> notes)
{
adapter.setNotes(notes);
}
});
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="500dp"
android:layout_marginRight="50dp"
android:background="#color/cardview_shadow_start_color"
android:maxLines="1"
android:text="Open new Activity!"
android:textColor="#color/black"
android:textSize="20dp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="100dp"
android:id="#+id/recycler_view111"
android:layout_width="match_parent"
android:layout_height="114dp"
tools:listitem="#layout/testing" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
testing.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"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="#+id/text_view_priority1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:textColorHighlight="#color/black"
android:text="1"
android:textAppearance="#style/TextAppearance.AppCompat.Large" />
<TextView
android:id="#+id/text_view_title1"
android:layout_width="323dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginStart="183dp"
android:layout_toStartOf="#id/text_view_priority1"
android:ellipsize="end"
android:maxLines="1"
android:text="Title1"
android:textAppearance="#style/TextAppearance.AppCompat.Large" />
<TextView
android:id="#+id/text_view_description1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="#id/text_view_title1"
android:text="Description1" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
The second activity is based on a class called AllWordsActivity" which uses activity_all_words which uses note_item test - code as follows:
AllWordsActivity.java
private NoteViewModel noteViewModel;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_all_words);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
NoteAdapter adapter = new NoteAdapter();
recyclerView.setAdapter(adapter);
//noteViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>()
{
#Override
public void onChanged(List<Note> notes)
{
adapter.setNotes(notes);
}
});
activity_all_words.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AllWordsActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="488dp"
tools:listitem="#layout/note_item" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
note_item.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"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="#+id/text_view_priority"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentEnd="true"
android:textColor="#color/purple_500"
android:text="1"
android:textAppearance="#style/TextAppearance.AppCompat.Large"/>
<TextView
android:id="#+id/text_view_title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Title"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:maxLines="1"
android:layout_toStartOf="#id/text_view_priority"
android:layout_alignParentStart="true"
android:ellipsize="end"/>
<TextView
android:id="#+id/text_view_description"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_below="#id/text_view_title"
android:text="Description" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
Code for noteAdapter:
```public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder>
{
private List notes = new ArrayList<>();
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.note_item, parent, false);
return new NoteHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull NoteHolder holder, int position)
{
Note currentNote = notes.get(position);
holder.textViewTitle.setText(currentNote.getTitle());
holder.textViewDescription.setText(currentNote.getDescription());
holder.textViewPriority.setText(String.valueOf(currentNote.getPriority()));
}
#Override
public int getItemCount()
{
return notes.size();
}
public void setNotes(List<Note> notes)
{
this.notes = notes;
notifyDataSetChanged();
}```
The problem is that both activities use the same adapter for their list view: NoteAdapter adapter = new NoteAdapter();. In turn, NoteAdapter only inflates note_item.xml for each item in the list:
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.note_item, parent, false);
To fix this, you need to either change NoteAdapter to work with multiple layout files for its rows. Or you need to create a different adapter for each RecyclerView.
Original Answer:
It sounds like you are seeing the same items displaying in both of your recycler views. The problem is that both the MainActivity and the AllWordsActivity have these lines:
NoteAdapter adapter = new NoteAdapter();
recyclerView.setAdapter(adapter);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>()
{
#Override
public void onChanged(List<Note> notes)
{
adapter.setNotes(notes);
}
});
So both activities are getting data from the same ViewModel to display. To display different data, use a different ViewModel in the MainActivity.
p.s. I suggest using consistent naming. You have AllWordsActivity and NotesAdapater. Either use AllWords or Notes, but don't mix and match.
I tried a lot of solutions but no solution has worked for me.
I am getting data from the server and showing it inside a recycleview. The data shows fine but shows this error in the logcat
Access denied finding property "persist.vendor.log.tel_dbg"
E/RecyclerView: No adapter attached; skipping layout
E/RecyclerView: No adapter attached; skipping layout
sometimes when I refresh again and again the recyclerview becomes empty.
I am using viewpager consisting of 2 fragments inside a parent fragment.
this recycleview is using in a nested scrollview
some time data not showing
Code snippet:
homebuyer_adapter_recycler=new homebuyer_adapter_recycle(getActivity(), items);
LinearLayoutManager home = new LinearLayoutManager(getActivity());
home.setOrientation(LinearLayoutManager.VERTICAL);
allitemsgrid.setLayoutManager(home);
allitemsgrid.setAdapter(r);
Here is more about
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent,
final int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.items_view,parent,
false);
RecyclerView.LayoutParams lp = new
RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
v.setLayoutParams(lp);
ViewHolder viewHolder = new ViewHolder(v);
HERE IS MY item view
<?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"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
app:cardCornerRadius="6dp"
android:layout_marginBottom="3dp"
app:cardBackgroundColor="#color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="150dp">
<com.makeramen.roundedimageview.RoundedImageView
android:layout_width="match_parent"
android:layout_height="150dp"
app:riv_corner_radius="6dp"
android:id="#+id/image_items"
android:scaleType="fitXY"
/>
<com.makeramen.roundedimageview.RoundedImageView
android:layout_width="match_parent"
android:layout_height="150dp"
app:riv_corner_radius="6dp"
android:background="#drawable/blackshade"
android:scaleType="fitXY"/>
<TextView
android:id="#+id/items_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/_5sdp"
android:textColor="#color/white"
android:fontFamily="sans-serif-smallcaps"
android:paddingLeft="20dp"
android:text="Message" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:text="Timing"
android:padding="#dimen/_5sdp"
android:textColor="#color/white"
android:layout_alignParentBottom="true"
android:fontFamily="#font/mylight"
android:layout_alignParentRight="true"
android:textSize="10dp"
android:id="#+id/shoptimming"/>
</RelativeLayout>
<TextView
android:id="#+id/name_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:alpha="0.6"
android:fontFamily="#font/arimo_bold"
android:paddingLeft="20dp"
android:text="Name"
android:textColor="#color/black"
android:textSize="17dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:orientation="horizontal">
<TextView
android:id="#+id/minumum_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_weight="1"
android:drawablePadding="10dp"
android:fontFamily="sans-serif"
android:paddingLeft="20dp"
android:text="Minimum " />
<TextView
android:id="#+id/price_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="sans-serif"
android:gravity="left"
android:paddingLeft="20dp"
android:text="charges"
/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
Here is my adapter class
public class homebuyer_adapter_recycle extends RecyclerView.Adapter<homebuyer_adapter_recycle.ViewHolder> {
private ArrayList<seller_information> listData;
private LayoutInflater layoutInflater;
int lastpostition=-1;
Context context;
public homebuyer_adapter_recycle(Context aContext, ArrayList<seller_information> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(aContext);
context=aContext;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder
(#NonNull ViewGroup parent, final
int viewType) {
View v = LayoutInflater.from(parent.getContext()).
inflate(R.layout.items_view,parent, false);
ViewHolder viewHolder = new ViewHolder(v);
Log.i("inadapter","calling time");
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
phone_number_shop = listData.get(viewType).getPhonenumber();
homebuyer.Delivery_charges_shop =
listData.get(viewType).getDiliveryfee();
homebuyer.Shop_name = listData.get(viewType).getShopname();
homebuyer.minimum_order = listData.get(viewType).getMinorder();
//profession=items.get(i).getName();
// Toast.makeText(getActivity(),phn,Toast.LENGTH_SHORT).show();
all_and_cetegory_items items = new all_and_cetegory_items();
Bundle b = new Bundle();
b.putString("phone",homebuyer.phone_number_shop);
items.setArguments(b);
FragmentTransaction fragmentTransaction =
((AppCompatActivity)context).getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.replace(R.id.nav_host_fragment, items);
fragmentTransaction.addToBackStack(null).commit();
}
});
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.name.setText(listData.get(position).getShopname());
//
Picasso.with(context).load(listData.get(position)
.getShopimage()).into(holder.shopimage);
Glide.with(context).load(listData.get(position).getShopimage())
.into(holder.shopimage);
holder.dilivery.setText("Rs "+listData.get(position).getDiliveryfee()+"
Delivery fee");
holder.minorder.setText("Rs "+listData.get(position).getMinorder()+" minimum");
holder.items.setText(listData.get(position).getShopmessage());
holder.time.setText("Service Available
"+listData.get(position).getStartingtime()+" to
"+listData.get(position).getEndingtime());
Log.i("inadapter","calling time"+listData.get(position).getShopname());
}
#Override
public int getItemCount() {
return listData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView name;
TextView dilivery;
TextView items;
TextView minorder;
TextView time;
ImageView shopimage;
public ViewHolder(#NonNull View v) {
super(v);
name = (TextView) v.findViewById(R.id.name_item);
dilivery = (TextView) v.findViewById(R.id.price_item);
minorder = (TextView) v.findViewById(R.id.minumum_order);
items=(TextView)v.findViewById(R.id.items_all);
time=(TextView)v.findViewById(R.id.shoptimming);
shopimage=(ImageView) v.findViewById(R.id.image_items);
}
}
}
In error it is saying that the Adapter for RecylerView is not attached. So, try to add adapter to the layout using:
recyclerView.setAdapter(categoryAdapter);
I am assuming homebuyer_adapter_recycler is your adapter.
According to that, you haven't really set your adapter as the logcat is specifying.
Add the below code instead of allitemsgrid.setAdapter(r);
allitemsgrid.setAdapter(homebuyer_adapter_recycler);
If my assumption or suggestion is wrong, it is okay. It is probably because your question is not very clear and does not provide the necessary details. Please provide more details such as the adapter class code and what is allitemsgrid, homebuyer_adapter_recycler and r.
I have a cardview, with some widgets in, and a recycler view inside the card view. The cardview is the parent.
I want it to be that when anywhere in the cardview is clicked, the event to happen. However, now only when the top part of the card view is clicked it triggers, but not when I click on the recycler view.
I tried setting clickable in the recyclerview to false, and it doesn't work.
Here is my xml.
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_today"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp"
android:padding="5dp"
android:clickable="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:clickable="false"
android:gravity="center_vertical"
>
<ImageView
android:layout_width="20dp"
android:layout_marginLeft="5dp"
android:layout_height="20dp"
android:clickable="false"
android:src="#drawable/today_icon_small"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:text="I still need to have today"
android:layout_margin="5dp"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/today_recycler_view_summary"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:clickable="false"
android:paddingBottom="10dp">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</android.support.v7.widget.CardView>
And here is the code of the click listener I do on the activity oncreate():
todayCardView = (CardView) findViewById(R.id.card_view_today);
todayCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Today card tapped");
Intent intent = new Intent(MainActivity.this, TodayActivity.class);
startActivity(intent);
}
});
As requsted, here is my adapter and view holder, for the recycler view, which is in the card view.
public class SummaryRecyclerViewAdapter extends RecyclerView.Adapter<SummaryRecyclerViewAdapter.ViewHolder> {
String[] todaysItems;
public SummaryRecyclerViewAdapter(String[] todaysItems) {
this.todaysItems = todaysItems;
}
#Override
public SummaryRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_chip,parent,false);
return new SummaryRecyclerViewAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(SummaryRecyclerViewAdapter.ViewHolder holder, int position) {
holder.textView.setText(todaysItems[position]);
}
#Override
public int getItemCount() {
return todaysItems.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView textView;
public ViewHolder(View v){
super(v);
textView = (TextView)v.findViewById(R.id.chip_text_view);
}
}
}
Add this for the recycler view .This makes sure that the child view will not handle the touch event .
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
return false;
}
Read this article to better understand the touch input flow .
http://balpha.de/2013/07/android-development-what-i-wish-i-had-known-earlier/
I have a custom view adapter with four buttons and a title that populate a ListView.
When a user clicks one of those buttons, I want to retrieve the title associated with that specific adapter.
So far I have tried retrieving the parent and getting the textView but that does not return the correct title.
So...how would I get the specific title affiliated to the adapter that has the button the user clicked on?
I'd be happy to clarify if you need more information.
Here is the layout of the adapter.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/fragment_student_home_classTitle_textView"
android:paddingTop="20dp"
android:layout_toLeftOf="#+id/linearLayout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="#+id/linearLayout">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_grades"
android:background="#ffff130c" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment_student_home_grades_imageButton"
android:src="#drawable/ic_grades_512"
android:background="#00000000" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_notification_textEdit"
android:background="#ffff130c" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment_student_home_notification_imageButton"
android:src="#drawable/ic_bell_512"
android:background="#00000000" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_homework"
android:background="#ffff130c" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment_student_home_homework_imageButton"
android:src="#drawable/ic_foundation_book_bookmark_simple_black_512x512"
android:contentDescription="#string/homework_notification_icon"
android:background="#00000000" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_attendance"
android:background="#ffff130c" />
<ImageButton
android:layout_width="42dp"
android:layout_height="40dp"
android:id="#+id/fragment_student_home_attendance_imageButton"
android:src="#drawable/ic_attendance"
android:contentDescription="#string/homework_notification_icon"
android:background="#00000000" />
</LinearLayout>
</LinearLayout>
And here is the adapter where I implemented the onClick
public class ClassAdapter extends ArrayAdapter<SchoolClass> implements View.OnClickListener{
private SchoolClass aClass;
public ClassAdapter(Context context, int resource, ArrayList<SchoolClass> objects) {
super(context, resource, objects);
}
public SchoolClass getSchoolClass(){
return this.aClass;
}
public void setSchoolClass(SchoolClass schoolClass){
this.aClass = schoolClass;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.classes_adapter, null);
}
aClass = getItem(position);
if(aClass != null){
TextView title = (TextView) v.findViewById(R.id.fragment_student_home_classTitle_textView);
if(title != null){
title.setText(aClass.getTitle());
}
setSchoolClass(aClass);
}
//set buttons
ImageButton notificationsButton = (ImageButton) v.findViewById(R.id.fragment_student_home_notification_imageButton);
ImageButton gradesButton = (ImageButton) v.findViewById(R.id.fragment_student_home_grades_imageButton);
ImageButton attendanceButton = (ImageButton) v.findViewById(R.id.fragment_student_home_attendance_imageButton);
ImageButton homeworkButton = (ImageButton) v.findViewById(R.id.fragment_student_home_homework_imageButton);
notificationsButton.setOnClickListener(this);
gradesButton.setOnClickListener(this);
attendanceButton.setOnClickListener(this);
homeworkButton.setOnClickListener(this);
return v;
}
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), ClassActivity.class);
View parent = (View) v.getRootView();
//v.getParent() returns null when I look for the textView
TextView title = (TextView) parent.findViewById(R.id.fragment_student_home_classTitle_textView);
System.out.println("\n\n title: " + title.getText().toString() + " \n\n");
intent.putExtra("__CLASS_NAME__", title.getText().toString());
It populates a list view and if I were to click on fragment_student_home_attendance_imageButton I would want to get the fragment_student_home_classTitle_textView associated with that ClassAdapter.
Just give a idea to you, hope this can help to fix the problem :)
#Override
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
// ....
ImageButton notificationsButton = (ImageButton) v.findViewById(R.id.fragment_student_home_notification_imageButton);
notificationsButton.setTag(R.id.fragment_student_home_notification_imageButton);
// ....
return v;
}
#Override
public void onClick(View v) {
if(v!=null && v.getTag()!=null && v.getTag()==R.id.fragment_student_home_notification_imageButton){
// do something you like
}
}
Ok nevermind, I got it.
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), ClassActivity.class);
//It's the parent of the parent OF THE parent where
//the textView lies in my layout.
View parent = (View) v.getParent().getParent().getParent();
TextView title = (TextView) parent.findViewById(R.id.fragment_student_home_classTitle_textView);
System.out.println("\n\n title: " + title.getText().toString() + " \n\n");
intent.putExtra("__CLASS_NAME__", title.getText().toString());
If there is a better way to get this solution, as it seems like a head on approach to the problem, I welcome any comments!
I've wrote a small application, which shows several android cards. But I'd like to be able to set a colour and title to the top of the card like in the image below, so far I haven't found any information online how to do this. So some help would be fantastic :-)
(My code so far does not accomplish the above, so far my code just produces regular all white cardviews)
My code so far is below:
CardAdapter.java
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
public List<TTItem> posts = new ArrayList<>();
public void addItems(List<TTItem> items) {
posts.addAll(items);
notifyDataSetChanged();
}
public void clear() {
posts.clear();
notifyDataSetChanged();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
View view = View.inflate(context, R.layout.item_cardview, null);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(posts.get(position).title);
Picasso.with(holder.mImageView.getContext()).load(posts.get(position).images[0]).into(holder.mImageView);
}
#Override
public int getItemCount() {
return posts.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ImageView mImageView;
public ViewHolder(View view) {
super(view);
mTextView = (TextView) view.findViewById(R.id.textview);
mImageView = (ImageView) view.findViewById(R.id.imageView);
}
}
}
MainActivity.java
public class MainActivity extends ActionBarActivity implements SwipeRefreshLayout.OnRefreshListener {
#InjectView(R.id.mainView)
RecyclerView mRecyclerView;
#InjectView(R.id.refreshContainer)
SwipeRefreshLayout refreshLayout;
private LinearLayoutManager mLayoutManager;
private CardAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
mRecyclerView.setHasFixedSize(true);
refreshLayout.setOnRefreshListener(this);
TypedValue tv = new TypedValue();
int actionBarHeight = 0;
if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}
refreshLayout.setProgressViewEndTarget(true, actionBarHeight);
mAdapter = new CardAdapter();
mRecyclerView.setAdapter(mAdapter);
// use a linear layout manager
mLayoutManager = new GridLayoutManager(this, 1);
mRecyclerView.setLayoutManager(mLayoutManager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return super.onOptionsItemSelected(item);
}
#Override
public void onRefresh() {
mAdapter.clear();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
refreshLayout.setRefreshing(false);
}
}, 2500);
}
}
Activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/refreshContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/mainView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
item_cardview.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="200dp"
android:layout_height="200dp"
android:padding="10dp"
card_view:cardCornerRadius="2dp"
card_view:contentPadding= "5dp"
card_view:cardUseCompatPadding="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"/>
<TextView
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:layout_gravity="center"/>
</LinearLayout>
</android.support.v7.widget.CardView>
The only change I've made from yours is, card_view:cardCornerRadius="8dp"> and removed the imageview(as no longer needed)
Screenshot of flashcard not filling to half of card:
I believe this is (almost) exact layout of what you want. It is pretty self-explanatory but feel free to ask if something's not clear.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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"
android:layout_gravity="center"
app:cardElevation="8dp"
card_view:cardCornerRadius="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout <!-- This is the specific part you asked to color -->
android:id="#+id/heading_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/teal_500"
android:padding="36dp"
android:orientation="vertical">
<TextView
android:id="#+id/tv_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="22 mins to Ancona"
android:textColor="#color/white"
android:textStyle="bold"
android:textSize="36sp" />
<TextView
android:id="#+id/tv_subheading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_below="#+id/tv_heading"
android:text="Light traffic on ss16"
android:textColor="#color/teal_200"
android:textSize="24sp" />
</LinearLayout>
<ImageView
android:id="#+id/iv_map"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="Assigned delivery boy"
android:scaleType="fitXY"
android:src="#drawable/bg_map" />
<TextView
android:id="#+id/tv_footer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_below="#+id/tv_heading"
android:text="It is just an example!"
android:textColor="#color/grey_500"
android:textStyle="bold"
android:textSize="24sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
I have replaced your mapFragment (presumably) with imageView to reduce complications.
Update: As the question now addresses the infamous "round corner" problem, this is actually by design. Yes, it is a big flaw. But the solution (as given in docs Here) would be to use card_view:cardPreventCornerOverlap="false" attribute (which I don't think does anything good because it just makes card square again).
See these questions for a good reference to this problem:
Appcompat CardView and Picasso no rounded Corners
Make ImageView fit width of CardView
From my understanding, you can change the colour of a CardView in it's entirety but not parts of it. I'm not sure how that would even work.
What you can do, is nest a TextView with the title within the CardView, then colour the background of the TextView to the colour you would like. Use appropriate margins/padding for a uniform look. Add a background to your TextView and see what you get.
Your TextView is already using the match_parent parameter on your android:layout_width="" so you would only need to add the background like so:
<TextView
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:layout_gravity="center"
android:background="#FF4444"/>
To change the entire CardView colour like I mentioned at the beginning you can do it the same way or programmatically like so:
cardView.setCardBackgroundColor(COLOURHERE);