View inside of RecyclerView is returning null - android

I am trying to set an onClickListener to my CheckBox but my checkBox instance is returning null on the onClickListener giving me a nullPointerException. I have looked at other questions similar to mine and haven't found anything that worked. I'm not too familiar with RecyclerView so I would not be surprised if it has something to do with how I'm initializing the view.
Here is the code in question-
Months0Through6.java
public class Months0Through6 extends android.support.v4.app.Fragment {
public Months0Through6() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
CheckBox checkBox;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_blank, container, false);
//This is returning null
checkBox = (CheckBox)rootView.findViewById(R.id.checkBox_ID);
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv_recycler_view);
rv.setHasFixedSize(true);
MilestonesAdapter adapter = new MilestonesAdapter(new String[]{"Month 0 stuff", "Example Two", "Example Three", "Example Four", "Example Five" , "Example Six" , "Example Seven"});
rv.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(),
"Your Message", Toast.LENGTH_LONG).show();
}
});
return rootView;
}
card_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="68dp">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="62dp"
card_view:cardCornerRadius="4dp"
card_view:elevation="14dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="#+id/checkBox_ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/tv_text"
android:layout_toRightOf ="#+id/checkBox_ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center" >
</TextView>
<TextView
android:id="#+id/tv_blah"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Another Recyclerview Fragment"
android:layout_below="#+id/tv_text"
android:layout_toRightOf="#+id/checkBox_ID"
android:layout_toEndOf="#+id/checkBox_ID">
</TextView>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>

Your checkbox is inside card_item layout. But you are inflating fragment_blank and trying to map checkbox to that layout.
You could map checkbox inside view holder and set onclick listener inside onBindViewHolder of adapter class

You should findViewById in your MilestonesAdapter, MilestonesAdapter is responsible for creating items for the RecyclerView.
See the guide from Android Developers site.
Check the stuff about onBindViewHolder.

Related

Setting Background of card View and scroll animations

Also I was trying to set background of my a card View used in recycler view in my app for that i did the following
card xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
android:layout_height="120dp"
android:layout_width="200dp"
android:layout_margin="5dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="5dp">
<LinearLayout
android:id="#+id/home_card_subject"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:textColor="#ffffff"
android:id="#+id/home_card_subject_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="#string/subject_text"
android:textSize="30sp"
android:gravity="bottom|center_horizontal"
android:padding="5dp"
android:layout_weight="70"/>
<TextView
android:textColor="#ffffff"
android:id="#+id/home_card_credits"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="4 credits"
android:gravity="center_horizontal"
android:layout_weight="30"
/>
</LinearLayout
>
</androidx.cardview.widget.CardView>
dashboard fragment:
package com.example.app100.ui.home;
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
LinearLayout cardView;
private ArrayList<Subject> subject = new ArrayList<>();
private DatabaseHelper databaseHelper;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
databaseHelper = new DatabaseHelper(getContext());
populateArrayList();
//homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
cardView = root.findViewById(R.id.home_card_subject);
/*final TextView textView = root.findViewById(R.id.text_home);
homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});*/
Random rand = new Random();
int rand_int1 = rand.nextInt(3);
switch (rand_int1){
case 0:
cardView.setBackgroundResource(R.drawable.gradient_color1);
break;
case 1:
cardView.setBackgroundResource(R.drawable.gradient_color2);
break;
case 2:
cardView.setBackgroundResource(R.drawable.gradient_color3);
break;
}
RecyclerView recyclerView = (RecyclerView) root.findViewById(R.id.home_recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext() , LinearLayoutManager.HORIZONTAL , false));
recyclerView.setAdapter(new RecyclerAdapter(subject));
// recycle.setLayoutManager(new GridLayoutManager( getActivity(),2));
// recycle.setAdapter(new RecyclerAdapter(subList));
return root;
}
private void populateArrayList(){
Log.d(TAG , "populating array list");
Cursor data = databaseHelper.getdata();
while(data.moveToNext()){
Subject sub = new Subject(data.getString(0) , data.getInt(1), data.getInt(2),
data.getInt(3), data.getInt(4),data.getInt(5) , data.getInt(6));
subject.add(sub);
}
}
}
but doing this gave the following errors:
2020-04-09 12:18:18.142 15575-15575/com.example.app100 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app100, PID: 15575
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.LinearLayout.setBackgroundResource(int)' on a null object reference
at com.example.app100.ui.home.HomeFragment.onCreateView(HomeFragment.java:65)
I wanted a scroll effect where the bottom part scrolls over the the top part like in the image bellowlike the image below the whiete part would scroll over the purple part and not scroll with it.
You are did not defined any id to cardview, and give linear layout reference to the cardview so cardview become null and occur Null pointer Exception. Please set id to cardView and give that id reference to the cardView.

OnClick Listener is not triggered inside a fragment with View Pager

I'd like to be able to set a View.OnclickListener to an ImageView inside a page (fragment) of my ViewPager, I don't want to click on the whole page of my ViewPager, I just want to be able to click on a specifig ImageView. I followed these questions (onClick not triggered on LinearLayout with child, How to set OnClickListener in ViewPager
) but they did not help me. This is my actual code:
MyPageFragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="240dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:focusableInTouchMode="true"
android:id="#+id/container_linear"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop" />
</LinearLayout>
</LinearLayout>
MyActivity.xml
<android.support.v4.view.ViewPager
android:id="#+id/product_view_pager"
android:layout_width="match_parent"
android:layout_height="240dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:gravity="center"
android:overScrollMode="never" />
MyFragment.class (where I'm binding the views using Butterknife)
#BindView(R.id.container_linear)
LinearLayout mContainer;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View mRootView = inflater.inflate(R.layout.my_layout, container, false);
ButterKnife.bind(this, mRootView);
mContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Test", "Clicked!");
}
});
}
Thanks for your support.
One thing to consider would be moving your OnClickListener to the parent LinearLayout you're setting as clickable and seeing if that helps.
Another thing is adding android:focusableInTouchMode="true" to the view you're attaching your OnClickListener to.
Other than that, you might want to share the code for registering the OnClickListener so we can investigate other possible errors.
If I understand correctly you want to click on the image view insideMyPageFragment.xml. This is simple but you need to give ID to the ImageView and refer it in your onCreateView method like you do for LinearLayout and then use onClickListener on that image.
So with recent conversation it seems that in linear layout you need to remove line clickable="false"
Basically that has blocked all the clicks on its children, thus that linear layout as well as the imageview clicks are not working for you. See this code I removed that line. Hope this works
Follow this code.
MyPageFragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:duplicateParentState="true"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="240dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:focusableInTouchMode="true"
android:id="#+id/container_linear"
android:gravity="center"
android:orientation="vertical">
<--you need to give ID to the view to be able to
perform events on them specifically.-->
<ImageView
android:id="#+id/my_awesome_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop" />
</LinearLayout>
Now in your MyFragment.class
#BindView(R.id.container_linear)
LinearLayout mContainer;
//declare with butterknife
#BindView(R.id.my_awesome_image)
ImageView myAwesomeImage;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View mRootView = inflater.inflate(R.layout.my_layout, container, false);
ButterKnife.bind(this, mRootView);
//you set click listener previously on entire linear layout instead of imageview
//that's why it was not reflecting on imageview click.
myAwesomeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG , "Awesome Imageview clicked!");
}
});
}
I solved this issue using the following chunk of code:
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
view.setOnClickListener(new OnClickListener(){
public void onClick(View v){
/* Do as you please here. */
}
});
}
The reference for this answer can be viewed here: How to detect click on ImageView in ViewPager's PagerAdapter (android)?

update fragment when taskadapter is empty

I have a fragment that has a listView which has an adapater, in the adapter class, there are buttons that remove objects from the adapter and then the adapter calls notifyDataSetChanged(); In the event that the adapter is empty I want the fragment to know and do something, is there a simple way to do this?
u can set a textview in your fragment xml file.Like this:
<?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="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tV_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerVertical="true"
android:text="No item yet"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="#+id/lv_notebook"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#android:color/transparent" />
</RelativeLayout>
When the adapter is empty,you can use textView.setVisible(VISIBLE).( you can search name).When the adapter has some items,you can use textView.setVisible(...)
Well,you can do like this in your fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
// set up listview
if(mDataList.size()==0){
mListView.setVisibility(View.GONE);
mTextView.setVisibility(View.VISIBLE);
}else{
YourAdapter mAdapter = new YourAdapter(mDataList...)
mListView.setAdapter(mAdapter);
mListView.setVisibility(View.VISIBLE);
mTextView.setVisibility(View.GONE);
}
return rootView;
}
public void deleteItem(int position){
Data item = mDataList.get(position);
mDataList.remove(item);
if(mDataList.size()==0){
mTextView.setVisibility(View.INVISIBLE);
}else{
mAdapter.notifyDataChanged();
}
}
public void addItem(Data item){
.....
}

When declaring buttons different fragments does not recognize

I have a problem when declaring a button.
I will try to explain as specific as possible.
In my main Layout I have a Fragment containing a secondary Layout. In which I have several buttons.
My intention is that my main fichero.java to declare the buttons within the fragment.
Here we put the main Layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<fragment
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:name="josejuansosarodriguez.radioecca.conocecanarias.TrueoFalseFragment"
android:id="#+id/fragmentTrueFalse"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Grp1"
android:id="#+id/textGrp1"
android:textSize="25sp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"/>
<fragment
android:layout_width="fill_parent"
android:layout_height="450dp"
android:name="josejuansosarodriguez.radioecca.conocecanarias.Grp1FragmentP1"
android:id="#+id/fragmetaskGRP1"
android:layout_below="#+id/textGrp1"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp" />
</RelativeLayout>
Here we put the secondary Layout that has the buttons:
<?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="match_parent"
android:id="#+id/fragment_TrueorFalse">
<Button
android:layout_width="120sp"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="#string/buttontrue"
android:id="#+id/buttontrue"
android:layout_marginLeft="40dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" />
<Button
android:layout_width="120sp"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="#string/buttonfalse"
android:id="#+id/buttonfalse"
android:layout_marginRight="40dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
And here I leave the my main activity:
public class Grp1Fragment extends Fragment {
private Button buttonTrue;
private Button buttonFalse;
private Button buttonNextAsk;
private View view;
public Grp1Fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
buttonTrue = (Button) view.findViewById(R.id.buttontrue);
buttonTrue.setOnClickListener(this);
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_grp1, container, false);
return view;
}
My problem I find in the following line:
buttonTrue.setOnClickListener (this);
The message reads: View can not be in Applied to josejuansosarodriguez.radioecca.conocecanarias.Grp1Fragment
I hope I have spread far.
Thank you very much for everything, this forum is amazing.
Try this:
Note that you have to FIRST inflate the layout to make accesible the widgets of the layout.
Then you can "bind" the widgets, and finallly in this case, set the listeners to the buttons.
I set you a Log, if you need change it to Toast, or code
public class Grp1Fragment extends Fragment {
private Button buttonTrue;
private Button buttonFalse;
private Button buttonNextAsk;
private View view;
public Grp1Fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_grp1, container, false);
//Declare your widgets (Buttons)
buttonTrue = (Button) view.findViewById(R.id.buttontrue);
buttonFalse = (Button) view.findViewById(R.id.buttonfalse);
//Set the Listeners
buttonTrue.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Toast or Log, or whateber you need
Log.d("Fragment1" , "Button: True");
}
});
buttonFalse.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Toast or Log, or whateber you need
Log.d("Fragment1" , "Button: FAlse");
}
});
//return the view
return view;
}
void setOnClickListener(View.OnClickListener l)
requires a OnClickListener, which Grp1Fragment is not.
Use something like
buttonTrue.setOnClickListener(new View.OnClickListener() {
void onClick(View v) {
... // reaction on the button
}
});

Android, findViewById returns null

I'm writing some code for Android, the matter is that, when I call findViewById it returns me null, and I cannot understand why! I've been wasting my brain since yesterday, but I cannot figure out the solution. The goal is to set a layout as a header for a listView. Here is my code, respectively my header and my page:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/header"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp">
<TextView
android:text="#string/bydistance"
android:layout_gravity="left"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textSize="13dp"
android:gravity="center_horizontal"/>
<TextView
android:text="#string/byactivity"
android:layout_gravity="right"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textSize="13dp"
android:gravity="center_horizontal"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000"
>
<ListView
android:id="#+id/parkList"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:divider="#android:color/transparent"
android:dividerHeight="5.0dp">
</ListView>
</LinearLayout>
And here my code where I call the addheaderView:
public class NearMeFragment extends Fragment implements View.OnClickListener{
private FragmentManager fragmentManager;
#Override
public void onCreate(Bundle savedBundle){
super.onCreate(savedBundle);
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedBundle) {
View v = inflater.inflate(R.layout.park_list, container, false);
//TODO remove
make_test(v, container);
return v;
}
public void openTest(View view){
new LiveComment().show(getChildFragmentManager(), "dialog");
}
public void onClick(View view){
if (fragmentManager == null)
fragmentManager = getChildFragmentManager();
//if (view.getId() == R.id.test){
fragmentManager.beginTransaction().add(new LiveComment(), "livecomment").commit();
}
private void make_test(View v, ViewGroup container) {
ListView listView = (ListView) v.findViewById(R.id.parkList);
Park[] list = new Park[3];
list[0] = new Park("parco a", "acquasparta", false, false, 1, 2, 3);
list[1]=new Park("parco b", "perugia", false, false, 1, 2, 3);
list[2]=new Park("parco b", "perugia", false, false, 1, 2, 3);
ParkListAdapter adapter = new ParkListAdapter(v.getContext(), R.layout.small_park_container,list);
LinearLayout header = (LinearLayout) container.findViewById(R.id.header);
listView.addHeaderView(header);
listView.setAdapter(adapter);
}
}
The error is given at
listView.addHeaderView(header)
R.id.header is inside v not inside container.
Change
LinearLayout header = (LinearLayout) container.findViewById(R.id.header);
with
LinearLayout header = (LinearLayout) v.findViewById(R.id.header);
about the ViewGroup container to doc says:
If non-null, this is the parent view that the fragment's UI should be
attached to. The fragment should not add the view itself, but this can
be used to generate the LayoutParams of the view.
Edit: Since your header view is in another Layout you have to inflate it too:
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedBundle) {
View v = inflater.inflate(R.layout.park_list, container, false);
View header = inflater.inflate(R.layout.headerlayout, null);
//TODO remove
make_test(v, header);
return v;
}
and
private void make_test(View v, View header) {
// your code
// you have to remove LinearLayout header = (LinearLayout) container.findViewById(R.id.header);
listView.addHeaderView(header);
listView.setAdapter(adapter);
}

Categories

Resources