RecyclerView not replacing detail pane with fragment on item click - java

Everytime I click a recycler view item on a tablet, it opens an activity rather than replacing the detail pane with a fragment.
The following line of code is what I use to detect wheter the detail pane is present:
mTwoPane = Objects.requireNonNull(getActivity()).findViewById(R.id.detail_container) != null;
Any ideas on the correct location to put this line of code?
activity XML
<?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.widget.Toolbar
android:id="#+id/masterToolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
>
<LinearLayout
android:id="#+id/singleline_text_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="#+id/md_toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#android:style/TextAppearance.Material.Widget.ActionBar.Title"/>
</LinearLayout>
</android.widget.Toolbar>
<RelativeLayout
android:id="#+id/master_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
sw600dp activity XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.widget.Toolbar
android:id="#+id/masterToolbar"
android:layout_width="0dp"
android:layout_height="?actionBarSize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/detailBackgroundToolbar"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="#+id/singleline_text_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="#+id/md_toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#android:style/TextAppearance.Material.Widget.ActionBar.Title"/>
</LinearLayout>
</android.widget.Toolbar>
<RelativeLayout
android:id="#+id/master_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/divider"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/masterToolbar" />
<View
android:id="#+id/divider"
android:layout_width="1dp"
android:layout_height="0dp"
android:background="?attr/dividerColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/masterToolbar"
app:layout_constraintTop_toBottomOf="#+id/masterToolbar" />
<android.widget.Toolbar
android:id="#+id/detailBackgroundToolbar"
android:layout_width="0dp"
android:layout_height="?actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintStart_toEndOf="#+id/masterToolbar"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.CardView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="4dp"
app:cardCornerRadius="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/divider"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.5">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/toolbar_dualline"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v7.widget.CardView>
<View
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/divider"
app:layout_constraintTop_toBottomOf="#+id/detailBackgroundToolbar" />
</android.support.constraint.ConstraintLayout>
Fragment class
public class MyFragment extends Fragment {
public MyFragment() {}
List<Product> wcList;
RecyclerView mRecyclerView;
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet device.
*/
public boolean mTwoPane;
public static MyFragment newInstance() {
return new MyFragment();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
mTwoPane = Objects.requireNonNull(getActivity()).findViewById(R.id.detail_container) != null;
mRecyclerView = view.findViewById(R.id.recyclerView_list);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
mRecyclerView.addItemDecoration(new DividerItemDecoration(Objects.requireNonNull(getContext()), LinearLayout.VERTICAL));
myList = new ArrayList<>();
String[] items = getResources().getStringArray(R.array.product_names);
String[] itemDescriptions = getResources().getStringArray(R.array.product_descriptions);
for (int n = 0; n < items.length; n++){
Product desserts = new Product();
desserts.setProductName(items[n]);
wdessertsc.setProductDescriptions(itemDescriptions[n]);
myList.add(desserts);
}
MyListAdapter listAdapter = new MyListAdapter(getActivity(), myList);
mRecyclerView.setAdapter(listAdapter);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
mTwoPane = Objects.requireNonNull(getActivity()).findViewById(R.id.detail_container) != null;
super.onActivityCreated(savedInstanceState);
}
}
Adapter class
public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.MyViewHolder> {
public boolean mTwoPane;
private Context mCtx;
private List<Product> myList;
public MyListAdapter(Context mCtx, List<Product> myList) {
this.mCtx = mCtx;
this.myList = myList;
}
#NonNull
#Override
public MyListAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.listitem_dualline, parent,false);
return new MyListAdapter.MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyListAdapter.MyViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: called.");
final Product product = myList.get(holder.getAdapterPosition());
holder.textviewTitle.setText(product.getProductName());
holder.textviewSubtitle.setText(product.getPRoductDescription());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Fragment newFragment;
if (product.getStationName().equals(v.getResources().getString(R.string.product_1))) {
newFragment = new FragmentProduct1();
} else {
newFragment = new FragmentProdcut2();
}
MyActivity activity = (MyActivity) v.getContext();
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.detail_container, newFragment);
transaction.commit();
} else {
Intent intent;
if (product.getStationName().equals(v.getResources().getString(R.string.product_1))) {
intent = new Intent(v.getContext(), Product1Activity.class);
} else {
intent = new Intent(v.getContext(), Product2Activity.class);
}
mCtx.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return myList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
RelativeLayout relativeLayout;
TextView textviewTitle, textviewSubtitle;
StationViewHolder(View itemView) {
super(itemView);
mTwoPane = itemView.findViewById(R.id.detail_container) != null;
relativeLayout = itemView.findViewById(R.id.listitem_relativelayout);
textviewTitle = itemView.findViewById(R.id.listitem_title);
textviewSubtitle = itemView.findViewById(R.id.listitem_subtitle);
}
}
}

This line mTwoPane = itemView.findViewById(R.id.detail_container) != null; from your view holder will always be false.
Why?
Because, your detail_container is not part of your view holder's item container, so itemView will always return null for your view. instead pass your boolean flag from your fragment to your adapter !

I think you are checking item two pan with recyclerview item xml
mTwoPane = itemView.findViewById(R.id.detail_container) != null;
That you can check while constructing recyclerview adapter and save it from the activity content view itself.

Related

RecyclerView not showing (displaying)

RecyclerView is not showing at all. Only the TextView is displayed.
I looked at other questions and used all answers from previous questions.
Other answers suggested that recycler's width can't be set wrap content or that setAdapter should be called after setting layout manager and I meet these conditions.
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.main_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
final MainAdapter adapter = new MainAdapter();
recyclerView.setAdapter(adapter);
List<FirebaseProduct> firebaseProductList = new ArrayList<>();
firebaseProductList = getData(); //Here is my Firebase code
adapter.setList(firebaseProductList);
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/main_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/aktualne_produkty"
android:gravity="center"
android:background="#color/colorPrimary"
android:textAppearance="#style/TextAppearance.AppCompat.Large">
</TextView>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/main_recycler"
android:layout_height="wrap_content"
android:layout_width="match_parent"
tools:listitem="#layout/card_main"
android:layout_below="#id/main_text"/>
</RelativeLayout>
MainAdapter
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainHolder> {
private List<FirebaseProduct> productList = new ArrayList<>();
#NonNull
#Override
public MainHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_main, parent, false);
return new MainHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MainHolder holder, int position) {
FirebaseProduct product = productList.get(position);
Log.d("Prod holder", "name - " + product.getProductName());
Log.d("Prod holder", "num - " + product.getProductNumber());
holder.nameView.setText(product.getProductName());
holder.numView.setText(product.getProductNumber());
}
#Override
public int getItemCount() {
return productList.size();
}
public void setProductList(List<FirebaseProduct> productList1){
this.productList = productList1;
notifyDataSetChanged();
}
public List<FirebaseProduct> getList(){
return productList;
}
public static class MainHolder extends RecyclerView.ViewHolder{
private TextView nameView;
private TextView numView;
public MainHolder(View itemView){
super(itemView);
nameView = itemView.findViewById(R.id.product_name);
numView = itemView.findViewById(R.id.product_count);
}
}
}
card_main
<androidx.cardview.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:layout_weight="3">
<TextView
android:id="#+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
</TextView>
<TextView
android:id="#+id/product_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/product_name">
</TextView>
</RelativeLayout>
<ImageView
android:id="#+id/product_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:contentDescription="#string/product_description">
</ImageView>
</LinearLayout>
</androidx.cardview.widget.CardView>
You are calling adapter.setList(firebaseProductList); in MainActivity but the function name in MainAdapter is setProductList(). So change it to adapter. setProductList(firebaseProductList)
Also, you want to be sure getData(); in MainActivity should return a non-empty list. you can verify it using debugger or by just adding a log statement before adapter.setList(firebaseProductList). like this:
Log.d("LIST_SIZE", firebaseProductList.size()); //this will print list size
adapter.setList(firebaseProductList); //you have to change it to adapter. setProductList(firebaseProductList)

ListViewAdapter context on fragment activity error, what should I do?

Good night android masters. Please help me. maybe those of you who understand better than me can help me solve the problem I'm facing right now.
1 https://imgur.com/S2TU08q
I made a listview on the fragment. I stopped because I was confused how I proceeded. maybe the code below can help you solve my problem!
This is the fragment I made. I name it Frag_Tour.java
public class Frag_Tour extends Fragment {
ListView listView;
ListViewAdapterTour adapter;
String[] judul1;
String[] judul2;
String[] durasi;
String[] harga;
int[] gambarTour;
ArrayList<Model> arrayList = new ArrayList<Model>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.frag_tour, container, false);
judul1 = new String[]{"Paket Hemat", "Paket Reguler", "Paket Honeymoon"};
judul2 = new String[]{"Wisata Belitung", "Wisata Belitung", "Wisata Belitung"};
durasi = new String[]{"3 Hari 2 Malam", "4 Hari 3 Malam", "3 Hari 1 Malam"};
harga = new String[]{"Rp 750.000/pax", "Rp 750.000/pax", "Rp 750.000/pax"};
gambarTour = new int[]{
R.drawable.mercusuar_1, R.drawable.mercusuar_2, R.drawable.mercusuar_3
};
listView = rootView.findViewById(R.id.listView);
for (int i = 0; i < judul1.length; i++) {
Model model = new Model(judul1[i], judul2[i], durasi[i], harga[i], gambarTour[i]);
arrayList.add(model);
}
adapter = new ListViewAdapterTour(this, arrayList);
listView.setAdapter((ListAdapter) arrayList);
return rootView;
}
}
this is the xml file. frag_tour.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:id="#+id/parent_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
[2] https://imgur.com/ehPanZM
this is the ListViewAdapter that I have created. I named it ListViewAdapterTour.java
public class ListViewAdapterTour extends BaseAdapter {
Context mContext;
LayoutInflater inflater;
List<Model> modellist;
ArrayList<Model> arrayList;
public ListViewAdapterTour (Context context, List<Model> modellist) {
mContext = context;
this.modellist = modellist;
inflater = LayoutInflater.from(mContext);
this.arrayList = new ArrayList<Model>();
this.arrayList.addAll(modellist);
}
public class ViewHolder {
TextView Judul1, Judul2, Durasi, Harga;
ImageView GambarTour;
}
#Override
public int getCount() {
return modellist.size();
}
#Override
public Object getItem(int i) {
return modellist.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view==null){
holder = new ViewHolder();
view = inflater.inflate(R.layout.row_tour, null);
holder.Judul1 = view.findViewById(R.id.judul1);
holder.Judul2 = view.findViewById(R.id.judul2);
holder.Durasi = view.findViewById(R.id.durasi);
holder.Harga = view.findViewById(R.id.harga);
holder.GambarTour = view.findViewById(R.id.GambarTour);
view.setTag(holder);
}
else {
holder = (ViewHolder)view.getTag();
}
holder.Judul1.setText(modellist.get(position).getJudul1());
holder.Judul2.setText(modellist.get(position).getJudul2());
holder.Durasi.setText(modellist.get(position).getDurasi());
holder.Harga.setText(modellist.get(position).getHarga());
holder.GambarTour.setImageResource(modellist.get(position).getGambartour());
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (modellist.get(position).getJudul1().equals("Paket Hemat 3 Hari 2 Malam")){
Intent intent = new Intent(mContext, TourDetail.class);
intent.putExtra("contentTv","PAKET HEMAT");
mContext.startActivity(intent);
}
}
});
return view;
}
}
and this is the xml file. row_tour.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:focusableInTouchMode="true"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="#dimen/spacing_middle"
android:layout_weight="1"
app:cardCornerRadius="2dp"
app:cardElevation="2dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="170dp"
android:orientation="vertical">
<ImageView
android:id="#+id/GambarTour"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/mercusuar_1"
tools:ignore="ContentDescription" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/overlay_dark_20" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="#id/GambarTour"
android:layout_margin="#dimen/spacing_medium"
android:orientation="vertical"
tools:ignore="UselessParent">
<TextView
android:id="#+id/judul1"
style="#style/TextAppearance.AppCompat.Large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Paket Hemat"
android:textColor="#color/White"
android:textStyle="bold" />
<TextView
android:id="#+id/judul2"
style="#style/TextAppearance.AppCompat.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Wisata Belitung"
android:textColor="#color/White"
android:textStyle="bold" />
<TextView
android:id="#+id/durasi"
style="#style/TextAppearance.AppCompat.Caption"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/_3_hari_2_malam"
android:textColor="#color/White" />
</LinearLayout>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignEnd="#id/GambarTour"
android:layout_alignRight="#id/GambarTour"
android:layout_margin="#dimen/spacing_medium"
android:src="#drawable/ic_favorite_border"
android:tint="#color/White" />
<TextView
android:id="#+id/harga"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#id/GambarTour"
android:layout_alignRight="#id/GambarTour"
android:layout_alignBottom="#id/GambarTour"
android:layout_margin="#dimen/spacing_large"
android:background="#drawable/gradient_green"
android:padding="#dimen/spacing_xmedium"
android:text="Rp 750.000/pax"
android:textColor="#color/White" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
[3] https://imgur.com/h7WiBgK
and this is the code for the model.java that I use
package com.androidrion.sejengkalapp;
class Model {
private String judul1;
private String judul2;
private String durasi;
private String harga;
private int gambartour;
//constructor
Model(String judul1, String judul2, String durasi, String harga, int gambartour) {
this.judul1 = judul1;
this.judul2 = judul2;
this.durasi = durasi;
this.harga = harga;
this.gambartour = gambartour;
}
//getters
String getJudul1() {
return this.judul1;
}
String getJudul2() {
return this.judul2;
}
String getDurasi() {
return this.durasi;
}
String getHarga() {
return this.harga;
}
int getGambartour() {
return this.gambartour;
}
}
I hope the teachers and masters about Android can help me in solving this problem. what I want is row_tour.xml which I have designed to be listview in frag_tour.xml
[4] https://imgur.com/VLzOUiK
The context should be the activity holding the fragment. So instead of this in your adapter constructor, use getActivity()
adapter = new ListViewAdapterTour(getActivity(), arrayList);

Android: NullPointerException when adding an Adapter to a ListView [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am creating a ViewPager in activity_table.xml.
This ViewPager has two pages which both share the same layout: list.xml.
This layout contains a ListView which I am trying to create an Adapter for.
The app compiles correctly but crashes when it tries to add the said Adapter to the ListView with a
NullPointerException when attempting to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference.
I have heard that I have to "load" a layout before I can use the Views it contains, but I how do I do that?
I have tried setContentView(R.layout.list), but it throws the same error...
Table.java
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = (ViewPager) findViewById(R.id.container);
viewPager.setAdapter(sectionsPagerAdapter);
String[] tmp = new String[mainTable.length-2];
ListView listView = (ListView)findViewById(R.id.listView);
ListAdapter listAdapter = new ListAdapter(this,R.layout.list_item,tmp);
listView.setAdapter(listAdapter);
public static class TableFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section number";
public TableFragment() {
}
public static TableFragment newInstance(int sectionNumber) {
TableFragment fragment = new TableFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER,sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.list,container,false);
TextView title = (TextView) rootView.findViewById(R.id.title);
if(getArguments().getInt(ARG_SECTION_NUMBER) == 1)
title.setText("Heute");
else if(getArguments().getInt(ARG_SECTION_NUMBER) == 2)
title.setText("Morgen");
return rootView;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return TableFragment.newInstance(position + 1);
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "today";
case 1:
return "tomorrow";
}
return null;
}
}
public class ListAdapter extends ArrayAdapter<String> {
public ListAdapter(Context context, int textViewResourceId) {
super(context,textViewResourceId);
}
public ListAdapter(Context context, int resource, String[] items) {
super(context,resource,items);
}
#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.list_item, null);
}
String p = getItem(position);
if(p!=null) {
TextView grade = (TextView) v.findViewById(R.id.grade);
TextView hour = (TextView) v.findViewById(R.id.hour);
TextView course = (TextView) v.findViewById(R.id.course);
TextView teacher = (TextView) v.findViewById(R.id.teacher);
TextView room = (TextView) v.findViewById(R.id.room);
TextView description = (TextView) v.findViewById(R.id.description);
try {
grade.setText(tableData[position][1]);
hour.setText(tableData[position][2]);
course.setText(tableData[position][3]);
teacher.setText(tableData[position][4]);
room.setText(tableData[position][5]);
description.setText(tableData[position][6]);
} catch (ArrayIndexOutOfBoundsException e) {
return v;
}
}
return v;
}
}
activity_table.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="de.fuchstim.vertretungsplan.Table">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin"
android:layout_gravity="bottom|right"
app:srcCompat="#drawable/reload_arrow_white" />
</android.support.design.widget.CoordinatorLayout>
list.xml
<?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">
<TextView
android:text="Heute (25.10.16)"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/title"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.DialogWindowTitle"
android:textAlignment="center" />
<GridLayout android:layout_gravity="start"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/grade"
android:layout_height="wrap_content"
android:text="Klasse"
android:layout_row="0"
android:layout_column="0"
android:layout_width="0dp"
android:textSize="14sp"
android:layout_columnWeight="40"
android:paddingStart="10dp" />
<TextView
android:text="Stunde"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/hour"
android:layout_row="0"
android:layout_column="1"
android:layout_columnWeight="15"/>
<TextView
android:text="Lehrer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/teacher"
android:layout_row="0"
android:layout_column="3"
android:layout_columnWeight="15"/>
<TextView
android:text="Kurs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/course"
android:layout_row="0"
android:layout_column="2"
android:layout_columnWeight="15"/>
<TextView
android:text="Raum"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/room"
android:layout_row="0"
android:layout_column="4"
android:layout_columnWeight="15"/>
</GridLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:id="#+id/listView" />
</LinearLayout>
I have tried setContentView(R.layout.list), but it throws the same error...
First, you need to use setContentView(R.layout.activity_table) instead.
Second, you cannot find the ListView from the Activity, since it is contained within the Fragment layout.
See here? Your ListView is in the same layout as this title element, so you need to find the ListView here...
View rootView = inflater.inflate(R.layout.list,container,false);
TextView title = (TextView) rootView.findViewById(R.id.title);
Move that ListView code from the Activity to the Fragment. And use getActivity() for the Adapter within the Fragment instead of this to get the Context.
That is where the #+id/listView value exists. That layout is searched with rootView.findViewById.
Since, you did not get null pointer at this location :
ViewPager viewPager = (ViewPager) findViewById(R.id.container);
viewPager.setAdapter(sectionsPagerAdapter);
So, this means you are using :
setContentView(R.layout.activity_table);
Because viewpager is only in above layout, and since listview is not in this layout xml file, you get null pointer on :
ListView listView = (ListView)findViewById(R.id.listView);
ListAdapter listAdapter = new ListAdapter(this,R.layout.list_item,tmp);
listView.setAdapter(listAdapter);
because listview in null, not present in activity_table xml file.
You need to set adapter in OnCreateView() :
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.list,container,false);
TextView title = (TextView) rootView.findViewById(R.id.title);
// Add below ...
String[] tmp = new String[mainTable.length-2];
ListView listView = (ListView)rootView.findViewById(R.id.listView);
ListAdapter listAdapter = new ListAdapter(getActivity(),R.layout.list_item,tmp);
listView.setAdapter(listAdapter);
// ends here ...
if(getArguments().getInt(ARG_SECTION_NUMBER) == 1)
title.setText("Heute");
else if(getArguments().getInt(ARG_SECTION_NUMBER) == 2)
title.setText("Morgen");
return rootView;
}
Hope this helps !

Why is my RecyclerView not showing anything? / What happend if Recycler Adapter is set again after notifyDataSetChanged() called?

I am new to Android Programming and I've been trying to make a fragment which displays a list of items using RecyclerView. Everything seems fine and there is no error when I run the app.
Here is my code:
FriendsFragment.java
public class FriendsFragment extends android.support.v4.app.Fragment {
#Bind(R.id.friendList)
RecyclerView friendList;
RecyclerView.LayoutManager friendsManager;
FriendListAdapter friendListAdapter;
public FriendsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_friends, container, false);
ButterKnife.bind(this, view);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
friendList.setHasFixedSize(true);
friendsManager = new LinearLayoutManager(view.getContext());
friendList.setLayoutManager(friendsManager);
friendListAdapter = new FriendListAdapter(new ArrayList<Friends>());
friendList.setAdapter(friendListAdapter);
test();
friendListAdapter.notifyDataSetChanged();
friendList.setAdapter(friendListAdapter);
super.onViewCreated(view, savedInstanceState);
}
private void test() {
Friends friend = new Friends();
friend.setName("Junjie Saitamaria");
friendListAdapter.addNewFriend(friend);
}
}
FriendListAdapter.java
public class FriendListAdapter extends RecyclerView.Adapter<FriendListAdapter.ViewHolderFriend> {
private List<Friends> friendList;
public FriendListAdapter(List<Friends> friends) {
if(friends != null) {
friendList = friends;
}
}
public void addNewFriend(Friends friend) {
friendList.add(0, friend);
}
#Override
public ViewHolderFriend onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_friend, parent, false);
ViewHolderFriend viewHolder = new ViewHolderFriend(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolderFriend holder, int position) {
Friends currentFriend = friendList.get(position);
holder.friendName.setText(currentFriend.getName());
}
#Override
public int getItemCount() {
return friendList.size();
}
static class ViewHolderFriend extends RecyclerView.ViewHolder {
#Bind(R.id.friend_avatar)
public ImageView friendThumbnail;
#Bind(R.id.friend_name)
public TextView friendName;
Context currentContext = null;
public ViewHolderFriend(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
this.currentContext = itemView.getContext();
}
}
}
fragment_friends.xml
<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:layout_margin="10dp"
tools:context="com.cebuinstituteoftechnology_university.citumessenger.FriendsFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/friendList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true" >
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
list_item_friend.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="#+id/friends_card"
android:elevation="2dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- icon -->
<ImageView
android:id="#+id/friend_avatar"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:contentDescription="icon"
android:src="#drawable/avatar"
/>
<!-- title -->
<TextView
android:id="#+id/friend_name"
android:layout_width= "wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_toRightOf="#+id/friend_avatar"
android:layout_alignBaseline="#+id/friend_avatar"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="Name" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Looks everything fine except this extra line friendList.setAdapter(friendListAdapter); in below code:
friendList.setAdapter(friendListAdapter);
test();
friendListAdapter.notifyDataSetChanged();
friendList.setAdapter(friendListAdapter);
Replace above 3 lines with this and see :
friendList.setAdapter(friendListAdapter);
test();
friendListAdapter.notifyDataSetChanged();
Remove following line from onViewCreated() Method
friendList.setAdapter(friendListAdapter);
other code is fine.

setOnClickListener not firing with custom adapter and custom ListView

I've been spending a few hours on a problem and I still can't figure it out. The setOnClickListener in HotelOverviewFragment is not firing when I click an item in my ListView. However, the setOnClickListener does work from my custom adapter (NowArrayAdapter).
My question is: why the setOnClickListener not working in HotelOverviewFragment (Class where the ListView is shown)?
Here's a list of what I've tried:
Setting android:focusable="false", android:focusableInTouchMode="false", android:descendantFocusability="blocksDescendants" in the hotel_row_layout.xml and fragment_hotel_overview.xml.
Setting android:clickable on true and false. Both didn't work.
Changing from BaseAdapter implementation to arrayAdapter.
I tried different listeners in HotelOverviewFragment: setOnClickListener, setOnItemClickListener, setOnItemSelectedListener and setOnTouchListener. Unfortunately, none of those worked for me.
Here's my code:
Custom adapter
public class NowArrayAdapter extends ArrayAdapter<String> {
private Context context;
private ArrayList<String> values;
private Typeface typeface;
private static Hashtable fontCache = new Hashtable();
private LayoutInflater inflater;
private TextView item;
public NowArrayAdapter(Context context, ArrayList<String> commandsList) {
super(context, R.layout.hotel_row_layout, commandsList);
this.context = context;
values = new ArrayList<String>();
values.addAll(commandsList);
typeface = getTypeface(this.context, "fonts/Roboto-Light.ttf");
inflater = LayoutInflater.from(this.context);
}
static Typeface getTypeface(Context context, String font) {
Typeface typeface = (Typeface)fontCache.get(font);
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), font);
fontCache.put(font, typeface);
}
return typeface;
}
public View getView(int position, View convertView, ViewGroup parent) {
String myText = getItem(position);
if(convertView == null) {
convertView = inflater.inflate(R.layout.hotel_row_layout, parent, false);
item = (TextView) convertView.findViewById(R.id.maps_button);
item.setTypeface(typeface);
convertView.setTag(item);
} else {
item = (TextView) convertView.getTag();
}
item.setText(myText);
//myListItem.descText.setTextSize(14);
convertView.setOnClickListener(new View.OnClickListener() {
// WORKS!
#Override
public void onClick(View view) {
Log.d("click", "Don't look at me!");
}
});
return convertView;
}
}
Fragment
public class HotelOverviewFragment extends Fragment {
private static Hashtable fontCache = new Hashtable();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_hotel_overview, container, false);
ListView list = (ListView) v.findViewById(android.R.id.list);
// Set up listview and buttons
setUp(v, list);
// Inflate the layout for this fragment
return v;
}
static Typeface getTypeface(Context context, String font) {
Typeface typeface = (Typeface)fontCache.get(font);
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), font);
fontCache.put(font, typeface);
}
return typeface;
}
public void setUp(View v, ListView l){
TextView address = (TextView) v.findViewById(R.id.content);
TextView header = (TextView) v.findViewById(R.id.header);
TextView hotelName = (TextView) v.findViewById(R.id.hotelName);
Typeface typeface = getTypeface(getActivity(), "fonts/Roboto-Light.ttf");
address.setText("some street \nZipCode, City \nCountry \nEmail \nphoneNumber");
address.setTypeface(typeface);
header.setText("Hotel info");
header.setTypeface(typeface);
header.setTextSize(20);
hotelName.setText("Hotel name");
hotelName.setTypeface(typeface);
// Set up button
ArrayList<String> n = new ArrayList<String>();
n.add(0, "More info");
// Show button
NowArrayAdapter adapter = new NowArrayAdapter(getActivity(), n);
l.setAdapter(adapter);
// THIS IS THE STUFF I'VE BEEN TRYING
try {
l.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("click", "Success");
}
});
l.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("click", "Success");
}
});
l.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.d("click", "Success");
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
l.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("click", "Success");
return false;
}
});
}catch (Exception e){
Log.d("click", e + "");
}
}
}
Layout xml of HotelOverviewFragment
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context="com.example"
android:background="#ffebebeb">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="200dp"
android:src="#drawable/banner"
android:id="#+id/hotelBanner"
android:layout_gravity="top"
android:adjustViewBounds="false"
android:scaleType="fitXY" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Hotelname"
android:id="#+id/hotelName"
android:gravity="center"
android:textSize="40dp"
android:layout_alignBottom="#+id/hotelBanner"
android:layout_alignParentRight="false"
android:layout_alignParentLeft="false"
android:textColor="#ffc4c4c4"
android:layout_marginBottom="5dp" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="0dp"
android:background="#drawable/header_card">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/header"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:textColor="#android:color/primary_text_light"
android:layout_height="wrap_content"
android:text="Header"
android:layout_toRightOf="#+id/headerImage"
android:layout_centerVertical="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/headerImage"
android:src="#drawable/ic_action_live_help"
android:layout_centerVertical="true" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:background="#drawable/content_card">
<TextView
android:id="#+id/content"
android:layout_gravity="left|center_vertical"
android:layout_width="fill_parent"
android:layout_weight="1"
android:textColor="#android:color/primary_text_light"
android:layout_height="wrap_content"
android:text="Content"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
The custom xml for a listview item
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:background="#drawable/content_card">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/maps_button"
android:layout_gravity="left|center_vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:textColor="#android:color/primary_text_light"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true" />
<ImageView
android:src="#drawable/ic_action_arrow_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:layout_alignParentTop="false"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="false"
android:layout_centerVertical="true"
/>
</RelativeLayout>
</LinearLayout>
Thanks in advance.
Thanks to Daniel Nugent's suggestion I got it working. Removing the convertView.setOnClickListener() is part of the answer. I think it was blocking the other listeners in the HotelOverviewFragment.
My next mistake was that I used setOnClickListener on a ListView for testing.
setOnClickListener should be used for buttons not ListViews.
So after removing setOnClickListener all the other listeners started working.
Thanks for your time.

Categories