Last item in RecyclerView not shown - java

I have a recycle view that works fine but when the number of items is too big for them to fit on the screen and I scroll down, the last item is not shown. However, I can see through logging that a view holder has been created and bound successfully. Then if I add another item, the previous last item is shown at the end instead and so on. I would really appreciate it if you could help me.
public class ProdListAdapter extends RecyclerView.Adapter<ProdListItemViewHolder> implements Filterable {
public List<ProductListItem> prodListItems = null;
public List<ProductListItem> displayedProdListItems = null;
private int currListItemId;
private RecyclerView recyclerView;
private ProductsListFragment fragment;
private MainActivity activity;
public ProdListAdapter(ProductsListFragment fragment, MainActivity activity) {
System.out.println("LIST ADAPTER CONSTRUCTOR");
this.prodListItems = new ArrayList<>();
for (int i = 0; i < activity.products.size(); i++) {
Product currProd = activity.products.get(i);
System.out.println(currProd.getName() + " " + i);
//add category separator
if (i > 0 && !currProd.getCategory().equals(activity.products.get(i - 1).getCategory())) {
prodListItems.add(new ProductListCategory(currProd));
} else if (i == 0) {
prodListItems.add(new ProductListCategory(currProd));
}
prodListItems.add(new ProductListItem(currProd));
}
this.activity = activity;
this.displayedProdListItems = prodListItems;
this.currListItemId = 0;
this.fragment = fragment;
}
// Create new views (invoked by the layout manager)
#Override
public ProdListItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int idToUse = currListItemId % prodListItems.size();
boolean isCatSeparator = false;
ProductListItem currProdListItem = prodListItems.get(idToUse);
ConstraintLayout listItemView = (ConstraintLayout) LayoutInflater.from(parent.getContext())
.inflate(R.layout.product_list_item, parent, false);
if (currProdListItem.isCategorySeparator()) {
isCatSeparator = true;
}
if (!isCatSeparator) {
Product currProd = currProdListItem.getProduct();
}
System.out.println("CREATING: " + currProdListItem.getItemText());
System.out.println("idToUse: " + idToUse + " " + currProdListItem.getItemText());
ProdListItemViewHolder viewHolder = new ProdListItemViewHolder(listItemView, isCatSeparator, fragment, currProdListItem);
currListItemId++;
return viewHolder;
}
// (invoked by the layout manager)
// Replace the contents of a view by the item at index: itemIndex
#Override
public void onBindViewHolder(ProdListItemViewHolder viewHolder, int itemIndex) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
//update product item
ProductListItem newListViewItem = displayedProdListItems.get(itemIndex);
boolean newItemIsCatSeparator = newListViewItem.isCategorySeparator();
boolean oldItemIsCatSeparator = viewHolder.getProductListItem().isCategorySeparator();
if (!newItemIsCatSeparator) {
Product currProd = newListViewItem.getProduct();
}
System.out.println();
System.out.println(viewHolder.getProductListItem().getItemText() + " -> " + newListViewItem.getItemText());
System.out.println(viewHolder.getProductListItem().isCategorySeparator() + " TO " + newListViewItem.isCategorySeparator());
System.out.println("checked " + viewHolder.getProductListItem().isChecked() + " to " + newListViewItem.isChecked());
System.out.println();
if (newItemIsCatSeparator && oldItemIsCatSeparator) {
//System.out.println("1");
viewHolder.changeCategory(newListViewItem.getProduct());
} else if (!newItemIsCatSeparator && !oldItemIsCatSeparator) {
//System.out.println("2");
viewHolder.changeProduct(newListViewItem);
} else if (newItemIsCatSeparator && !oldItemIsCatSeparator) {
//System.out.println("3");
viewHolder.toCatSeparator(newListViewItem.getProduct());
} else { // !newListViewItem.isCategorySeparator() && viewHolder.getProductListItem().isCategorySeparator()
//System.out.println("4");
viewHolder.toProdItem(newListViewItem);
}
}
#Override
public int getItemCount() {
int count = 0;
if(this.displayedProdListItems != null){
count = displayedProdListItems.size();
}
return count;
}
}
public class ProductsListFragment extends Fragment {
private int numCheckedItems = 0;
private BottomSheetBehavior botSheetBehavior;
private boolean botSheetOpen = false;
private ProdListAdapter prodAdapter;
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_products_list, container, false);
//recyclerView stuff below
RecyclerView recyclerView = (RecyclerView) root.findViewById(R.id.prod_list_recycler_view);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext());
recyclerView.setLayoutManager(layoutManager);
prodAdapter = new ProdListAdapter(this, activity);
recyclerView.setAdapter(prodAdapter);
activity.setProdListAdapter(prodAdapter);
return root;
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/prodListLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<AutoCompleteTextView
android:id="#+id/searchTxtView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search"
android:drawableLeft="#drawable/ic_search"
android:drawablePadding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/prod_list_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dividerHeight="2dp"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/searchTxtView" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:layout_marginEnd="28dp"
android:layout_marginRight="28dp"
android:layout_marginBottom="28dp"
android:src="#drawable/ic_fab_plus_36dp"
app:backgroundTint="#aa00ff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

add:
app:layout_constraintBottom_toBottomOf="parent"
and change height of recyclerview to 0dp

Related

I want insert map fragment inside listview that use custom adapter

I want insert map fragment inside listview that use custom adapter
class TripAdapter
class TripAdapter extends ArrayAdapter<Trip> {
private List<Trip> trips;
public TripAdapter(#NonNull Context context, List<Trip> trips) {
super(context, 0);
this.trips = trips;
}
#Override
public int getCount() {
return trips.size();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater()
.inflate(R.layout.custom_past, parent, false);
}
TextView dateText = convertView.findViewById(R.id.dateText);
TextView timeText = convertView.findViewById(R.id.timeText);
TextView startText = convertView.findViewById(R.id.startText);
TextView endText = convertView.findViewById(R.id.endText);
TextView nameText = convertView.findViewById(R.id.nameText);
TextView notesText = convertView.findViewById(R.id.notesText);
TextView statusText = convertView.findViewById(R.id.statusText);
TextView typeText = convertView.findViewById(R.id.typeText);
Button deleteButton = convertView.findViewById(R.id.deleteButton);
MapFragment f = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
if (f != null)
getFragmentManager().beginTransaction().remove(f).commit();
Trip trip = trips.get(position);
dateText.setText(trip.tripdate);
timeText.setText(trip.triptime);
nameText.setText(trip.name);
notesText.setText("Notes: " + trip.notes);
startText.setText(trip.starttext);
endText.setText(trip.endtext);
statusText.setText("(" + trip.status + ")");
typeText.setText("(" + trip.type + ")");
startlat = Double.valueOf(trip.startlat);
startlongg = Double.valueOf(trip.startlongg);
endlat = Double.valueOf(trip.endlat);
endlongg = Double.valueOf(trip.endlongg);
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return convertView;
}
}
xml layout file
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D6D5D5"
tools:context=".UpcomingTrips">
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="0dp"
android:layout_height="150dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.494"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/notesText" />
</androidx.constraintlayout.widget.ConstraintLayout>
I want declare fragment inside TripAdapter
I want when list contains more than one trip add them in TripAdapter
and this is error
java.lang.IllegalArgumentException: Binary XML file line #140: Duplicate id 0x7f08009d, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.SupportMapFragment
at androidx.fragment.app.FragmentManagerImpl.onC
Thanks very much

How to set up onItemClickListener

I set up a Listview in Android Studio but need help with coding a OnItemClickListner.
I have tried the code, but doesn't seem to work.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.list_view);
ArrayList<Object> list = new ArrayList<>();
list.add(new LTCItem("30.06 Sign Violations","Submit A Complaint To Texas Attorney General",R.drawable.gavel));
list.add(new LTCItem("U.S. & Texas LawShield","Legal Defense For Self Defense",R.drawable.lawshield));
listView.setAdapter(new LTCAdapter(this, list));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
}
}
Below is my list_view file. Where in the file do block descendantFocusability as suggested? Do I put it under listView? Sorry I am learning .
<?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:alwaysDrawnWithCache="true"
android:background="#000000"
android:padding="8dp">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/itemListViewImgIcon"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="#+id/itemListViewImgIcon"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/itemListViewTxtTopicName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
<TextView
android:id="#+id/itemListViewTxtTopicSubtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/itemListViewTxtTopicName"
</RelativeLayout>
Ok I added the adapter code which is a Java Class item. Where do I add the code here?
public class LTCAdapter extends BaseAdapter {
ArrayList<Object> list;
private static final int LTC_Item = 0;
private static final int HEADER = 1;
private LayoutInflater inflater;
public LTCAdapter(Context context, ArrayList<Object> list) {
this.list = list;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getItemViewType(int position) {
if (list.get(position) instanceof LTCItem) {
return LTC_Item;
} else {
return HEADER;
}
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return 1;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
switch (getItemViewType(i)) {
case LTC_Item:
view = inflater.inflate(R.layout.item_list_view, null);
break;
case HEADER:
view = inflater.inflate(R.layout.item_listview_header, null);
break;
}
}
switch (getItemViewType(i)) {
case LTC_Item:
ImageView image = (ImageView) view.findViewById(R.id.itemListViewImgIcon);
TextView name = (TextView) view.findViewById(R.id.itemListViewTxtTopicName);
TextView subtitle = (TextView) view.findViewById(R.id.itemListViewTxtTopicSubtitle);
image.setImageResource(((LTCItem) list.get(i)).getImage());
name.setText(((LTCItem) list.get(i)).getName());
subtitle.setText(((LTCItem) list.get(i)).getSubtitle());
break;
case HEADER:
TextView title = (TextView) view.findViewById(R.id.itemListViewHeader);
title.setText(((String) list.get(i)));
break;
}
return view;
}
}
Your ListView element doesn't have an ID, you should add android:id="#+id/list_view" to it in the XML file.
Here is an example:
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
As your list view contains focusable elements, you need to write this piece of code in parent layout in your list view item xml file
android:descendantFocusability="blocksDescendants"

how to add image for headers in navigationdrawer in android

Hi in the below code in my project contains navigation drawer with expandable listview.
but everything was working fine. but want to display image for headers on leftside and arrow icon should be in right side for each header.
using json am parsing the data and in the same way want to display images for headers.
can any one help me how to do that one.
MainActivity.java:
public class MainActivity extends AppCompatActivity {
ArrayList<Model_country> al_main = new ArrayList<>();
ExpandableListView ev_list;
CountryAdapter obj_adapter;
String TAG = "MainActivity";
private DrawerLayout mDrawerLayout;
HomeFragment fragment;
TextView tv_name;
RelativeLayout rl_menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fn_data();
init();
}
private void init() {
getSupportActionBar().hide();
ev_list = (ExpandableListView) findViewById(R.id.ev_menu);
tv_name = (TextView) findViewById(R.id.tv_name);
rl_menu = (RelativeLayout) findViewById(R.id.rl_menu);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
obj_adapter = new CountryAdapter(MainActivity.this, al_main);
ev_list.setAdapter(obj_adapter);
ev_list.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
setListViewHeight(parent, groupPosition);
return false;
}
});
setExpandableListViewHeightBasedOnChildren(ev_list);
fragment = new HomeFragment();
Bundle bundle = new Bundle();
bundle.putString("name", al_main.get(0).getStr_country());
bundle.putString("des", al_main.get(0).getAl_state().get(0).getStr_description());
bundle.putString("dish", al_main.get(0).getAl_state().get(0).getStr_name());
bundle.putString("image", al_main.get(0).getAl_state().get(0).getStr_image());
tv_name.setText(al_main.get(0).getStr_country());
fragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, "HomeFragment").addToBackStack("null").commit();
rl_menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDrawerLayout.openDrawer(Gravity.LEFT);
}
});
}
private void setListViewHeight(ExpandableListView listView, int group) {
ExpandableListAdapter listAdapter = (ExpandableListAdapter) listView.getExpandableListAdapter();
int totalHeight = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.EXACTLY);
for (int i = 0; i < listAdapter.getGroupCount(); i++) {
View groupItem = listAdapter.getGroupView(i, false, null, listView);
groupItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += groupItem.getMeasuredHeight();
if (((listView.isGroupExpanded(i)) && (i != group))
|| ((!listView.isGroupExpanded(i)) && (i == group))) {
for (int j = 0; j < listAdapter.getChildrenCount(i); j++) {
View listItem = listAdapter.getChildView(i, j, false, null,
listView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
}
}
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
int height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getGroupCount() - 1));
/* if (height < 10)
height = 200;*/
params.height = height;
listView.setLayoutParams(params);
listView.requestLayout();
}
private void fn_data() {
String str_data = loadJSONFromAsset();
try {
JSONObject jsonObject_country = new JSONObject(str_data);
JSONArray jsonArray_country = jsonObject_country.getJSONArray("country");
al_main = new ArrayList<>();
for (int i = 0; i < jsonArray_country.length(); i++) {
Model_country obj_country = new Model_country();
JSONObject jsonObject = jsonArray_country.getJSONObject(i);
JSONArray jsonArray_dishes = jsonObject.getJSONArray("dishes");
ArrayList<Model_Dish> al_dishes = new ArrayList<>();
for (int j = 0; j < jsonArray_dishes.length(); j++) {
JSONObject jsonObject_dishes = jsonArray_dishes.getJSONObject(j);
Model_Dish obj_dish = new Model_Dish();
obj_dish.setStr_name(jsonObject_dishes.getString("dishname"));
obj_dish.setStr_description(jsonObject_dishes.getString("description"));
obj_dish.setStr_image(jsonObject_dishes.getString("image"));
al_dishes.add(obj_dish);
}
obj_country.setAl_state(al_dishes);
obj_country.setStr_country(jsonObject.getString("name"));
// obj_country.setStr_country (jsonObject.getString("image"));
al_main.add(obj_country);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public static void setExpandableListViewHeightBasedOnChildren(ExpandableListView expandableListView) {
CountryAdapter adapter = (CountryAdapter) expandableListView.getExpandableListAdapter();
if (adapter == null) {
return;
}
int totalHeight = expandableListView.getPaddingTop() + expandableListView.getPaddingBottom();
for (int i = 0; i < adapter.getGroupCount(); i++) {
View groupItem = adapter.getGroupView(i, false, null, expandableListView);
groupItem.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
totalHeight += groupItem.getMeasuredHeight();
if (expandableListView.isGroupExpanded(i)) {
for (int j = 0; j < adapter.getChildrenCount(i); j++) {
View listItem = adapter.getChildView(i, j, false, null, expandableListView);
listItem.setLayoutParams(new ViewGroup.LayoutParams(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED));
listItem.measure(View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalHeight += listItem.getMeasuredHeight();
}
}
}
ViewGroup.LayoutParams params = expandableListView.getLayoutParams();
int height = totalHeight + expandableListView.getDividerHeight() * (adapter.getGroupCount() - 1);
if (height < 10)
height = 100;
params.height = height;
expandableListView.setLayoutParams(params);
expandableListView.requestLayout();
}
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getAssets().open("dishes.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
Log.e(TAG, "Json response " + json);
return json;
}
public void fn_selectedPosition(int group, int child) {
fragment = new HomeFragment();
Bundle bundle = new Bundle();
bundle.putString("name", al_main.get(group).getStr_country());
bundle.putString("des", al_main.get(group).getAl_state().get(child).getStr_description());
bundle.putString("dish", al_main.get(group).getAl_state().get(child).getStr_name());
bundle.putString("image", al_main.get(group).getAl_state().get(child).getStr_image());
fragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, "HomeFragment").addToBackStack("null").commit();
mDrawerLayout.closeDrawer(Gravity.LEFT);
tv_name.setText(al_main.get(group).getStr_country());
}
activity_main:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:background="#234E6F"
android:layout_height="60dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textColor="#ffffff"
android:layout_centerInParent="true"
android:textStyle="bold"
android:id="#+id/tv_name"/>
<ImageView
android:layout_width="25dp"
android:layout_centerVertical="true"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:src="#drawable/menu_icon"/>
<RelativeLayout
android:layout_width="40dp"
android:id="#+id/rl_menu"
android:layout_height="match_parent"></RelativeLayout>
</RelativeLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#FFFFFF">
<include layout="#layout/menu_layout"></include>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
You can use expandable listview for this. use custom adapter which will have textview and imageview. set image and text using expandable listview adapter. you can use custom adapter for child and parent both
public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) {
if (view == null)
view = layoutInflater.inflate(R.layout.row_comment, viewGroup, false);
TextView username=(TextView) view.findViewById(R.id.userName);
((ImageView) view.findViewById(R.id.img_hifi)).setImageResource(R.drawable.high_5_icon_highlited);
}
#Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
if (view == null)
view = layoutInflater.inflate(R.layout.row_comment, viewGroup, false);
view.setBackgroundColor(Color.parseColor("#FFCC00"));
((TextView) view.findViewById(R.id.userName)).setText(getChild(i, i1).getUser_name() + " ");
((TextView) view.findViewById(R.id.userName)).setTextColor(Color.BLACK);
return view;
}

fragment recyclerview different view types not working

Android fragment recyclerview different view types not working
I have implement different view types using recyclerview adapter but list are empty this time not display empty view type.
First implement fragment
Second add recyclerview in fragment.
Fragment class
LocationAdapter locationAdapter = new LocationAdapter(getActivity(), locationList);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
rvLocationList.setLayoutManager(layoutManager);
rvLocationList.setAdapter(locationAdapter);
Adapter class
public class LocationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private ArrayList<LocationModel> locationlist;
private DataBaseHelper dataBaseHelper;
private OnItemClickListener onItemClickListener;
public final int EMPTY = 0;
public final int NOT_EMPTY = 1;
private String TAG = "LocationAdapter";
public LocationAdapter(Context context, ArrayList<LocationModel> list) {
this.mContext = context;
this.locationlist = list;
dataBaseHelper = new DataBaseHelper(context);
}
#Override
public int getItemViewType(int position) {
Log.d(TAG, "position = " + position);
if (locationlist.size() == 0) {
return EMPTY;
} else {
return NOT_EMPTY;
}
}
public void refreshData(ArrayList<LocationModel> tasks) {
locationlist.clear();
locationlist.addAll(tasks);
notifyDataSetChanged();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(mContext);
switch (viewType) {
case EMPTY:
View viewItem = inflater.inflate(R.layout.no_task_layout, parent, false);
viewHolder = new EmptyViewHolder(viewItem);
break;
case NOT_EMPTY:
View viewLoading = inflater.inflate(R.layout.location_list, parent, false);
viewHolder = new NotEmptyViewHolder(viewLoading);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (getItemViewType(position)) {
case EMPTY:
EmptyViewHolder emptyViewHolder = (EmptyViewHolder) holder;
emptyViewHolder.ivNoItem.getLayoutParams().height = R.dimen._30sdp;
emptyViewHolder.ivNoItem.getLayoutParams().width = R.dimen._30sdp;
emptyViewHolder.tvNoitem.setText("No Location.");
emptyViewHolder.tvAddItem.setText("Add Location");
break;
case NOT_EMPTY:
break;
}
}
#Override
public int getItemCount() {
return locationlist == null ? 0 : locationlist.size();
}
public class NotEmptyViewHolder extends RecyclerView.ViewHolder {
private ImageView ivFirstCharecter, ivMore;
private TextView tvName, tvAddress;
NotEmptyViewHolder(View itemView) {
super(itemView);
ivFirstCharecter = itemView.findViewById(R.id.ivFirstCharecter);
ivMore = itemView.findViewById(R.id.ivMore);
tvName = itemView.findViewById(R.id.tvName);
tvAddress = itemView.findViewById(R.id.tvAddress);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClickListener.OnItemClick(locationlist.get(getAdapterPosition()).getLocationName());
}
});
}
}
public class EmptyViewHolder extends RecyclerView.ViewHolder {
private ImageView ivNoItem;
private TextView tvNoitem, tvAddItem;
EmptyViewHolder(View itemView) {
super(itemView);
ivNoItem = itemView.findViewById(R.id.ivNoItem);
tvNoitem = itemView.findViewById(R.id.tvNoitem);
tvAddItem = itemView.findViewById(R.id.tvAddItem);
}
}
public void setOnItemClickListener(OnItemClickListener itemClickListener) {
onItemClickListener = itemClickListener;
}
public interface OnItemClickListener {
void OnItemClick(String locationName);
}
}
No layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llNoTask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/ivNoItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#drawable/ic_no_task" />
<TextView
android:id="#+id/tvNoitem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/semibold"
android:textColor="#color/black"
android:textSize="#dimen/_30sdp" />
<TextView
android:id="#+id/tvAddItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/regular"
android:textColor="#color/text_gray"
android:textSize="#dimen/_18sdp" />
Fragment layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvLocationList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="#dimen/_60sdp" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fbtnAddLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="#dimen/_10sdp"
android:gravity="center_vertical"
app:backgroundTint="#color/Red"
app:fabSize="normal"
app:srcCompat="#drawable/ic_add" />
Home activity
fragment = new LocationFragment();
try {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
} catch (IllegalStateException ieEx) {
ieEx.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
The empty item is itself an item. To be displayed the item count must not be 0, otherwise the other methods (getItemViewType(), onCreateViewHolder(), ...) are never called.
#Override
public int getItemCount() {
return locationlist == null ? 0 : Math.max(1, locationlist.size());
}
You may also return 1 if locationlist is null but you have to handle the case in other methods :
#Override
public int getItemViewType(int position) {
Log.d(TAG, "position = " + position);
if (locationlist == null || locationlist.size() == 0) {
return EMPTY;
} else {
return NOT_EMPTY;
}
}
Include no_task_layout.xml content in Fragment layout xml, set its Visibility to "gone", Then check if locationlist is empty in Fragment Class,
if(locationList.size > 0){ ///Set adapter to Recycler view
Otherwise set rvLocationList.setVisibility(View.GONE) and show the Empty View.

Android: GridView shows all but a few images

I have 6 images downloaded as shown here, but the GridView in my gallery only displays 5 of those images.
I'm trying to copy how Instagram displays its gallery, with a selected image taking up 60% of the screen and the gallery images taking up the rest.
fragment_gallery.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="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/relLayoutl">
<!--toolbar-->
<include layout="#layout/snippet_top_gallerybar"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="100"
android:layout_below="#+id/relLayoutl">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="60">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/galleryImageView"
android:scaleType="centerCrop"/>
<ProgressBar
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/progressBar"
android:layout_centerInParent="true"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="40">
<GridView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:numColumns="5"
android:verticalSpacing="1.5dp"
android:horizontalSpacing="1.5dp"
android:gravity="center"
android:layout_marginTop="1dp"
android:stretchMode="none"
android:id="#+id/gridView">
</GridView>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
I created a square view to generate square cells
layout_grid_imageview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.example.sheldon.instagramclone.Util.SquareImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/gridViewImage"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
<ProgressBar
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:id="#+id/gridProgressBar"/>
</RelativeLayout>
GalleryFragment.java
public class GalleryFragment extends Fragment {
private static final int NUM_COLUMNS = 4;
private ImageView mExit;
private Spinner mSpinner;
private TextView mNext;
private ProgressBar mProgressBar;
private List<String> directories;
private GridView mGridView;
private ImageView mGalleryImage;
private HashMap<String, ArrayList<String>> directoryToImage;
private String append = "file:/";
private String mSelectedImage;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_gallery, container, false);
mExit = (ImageView) view.findViewById(R.id.exitShare);
mSpinner = (Spinner) view.findViewById(R.id.shareSpinner);
mNext = (TextView) view.findViewById(R.id.shareNext);
mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar);
mGridView = (GridView) view.findViewById(R.id.gridView);
mGalleryImage = (ImageView) view.findViewById(R.id.galleryImageView);
mExit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().finish();
}
});
mNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: Navigating to next step in sharing photo");
Intent intent = new Intent(getActivity(), NextActivity.class);
intent.putExtra("selected_image", mSelectedImage);
startActivity(intent);
}
});
init();
return view;
}
private void init() {
ImageFinder imageFinder = new ImageFinder();
imageFinder.getImages(getActivity());
directoryToImage = imageFinder.getImageMapping();
directories = new ArrayList<>(directoryToImage.keySet());
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.spinner_item, directories);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "onItemSelected: " + directories.get(position));
setUpGridView(directories.get(position));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
private void setUpGridView(String directory) {
final ArrayList<String> imgURLS = directoryToImage.get(directory);
Log.d(TAG, "setUpGridView: Displaying " + directory + " with " + imgURLS.size() + " images");
int gridWidth = getResources().getDisplayMetrics().widthPixels;
int imageWidth = gridWidth / NUM_COLUMNS;
Log.d(TAG, "setUpGridView: Image Width is " + imageWidth);
mGridView.setColumnWidth(imageWidth);
GridImageAdapter adapter = new GridImageAdapter(getActivity(), R.layout.layout_grid_imageview, append, imgURLS);
mGridView.setAdapter(adapter);
UniversalImageLoader.setImage(imgURLS.get(0),mGalleryImage, mProgressBar, append);
mSelectedImage = imgURLS.get(0);
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
UniversalImageLoader.setImage(imgURLS.get(position), mGalleryImage, mProgressBar, append);
mSelectedImage = imgURLS.get(0);
}
});}
I display the images using a library called Universal Image loader
GridImageAdapter.java
public class GridImageAdapter extends ArrayAdapter<String>{
private Context mContext;
private LayoutInflater mInflater;
private int layoutResource;
private String mAppend;
private ArrayList<String> imgURLs;
public GridImageAdapter(Context context, int layoutResource, String append, ArrayList<String> imgURLs) {
super(context, layoutResource, imgURLs);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContext = context;
this.layoutResource = layoutResource;
mAppend = append;
this.imgURLs = imgURLs;
}
private static class ViewHolder{
SquareImageView image;
ProgressBar mProgressBar;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
convertView = mInflater.inflate(layoutResource, parent, false);
holder = new ViewHolder();
holder.mProgressBar = (ProgressBar) convertView.findViewById(R.id.gridProgressBar);
holder.image = (SquareImageView) convertView.findViewById(R.id.gridViewImage);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
String imgURL = getItem(position);
Log.d(TAG, "getView: Loading position " + position + ", displaying " + imgURL + ", with image " + holder.image);
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.displayImage(mAppend + imgURL, holder.image, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
if(holder.mProgressBar != null){
holder.mProgressBar.setVisibility(View.VISIBLE);
}
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
if(holder.mProgressBar != null){
holder.mProgressBar.setVisibility(View.GONE);
}
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if(holder.mProgressBar != null){
holder.mProgressBar.setVisibility(View.GONE);
}
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
if(holder.mProgressBar != null){
holder.mProgressBar.setVisibility(View.GONE);
}
}
});
return convertView;
}
First time posting, so I apologize if there's anything wrong with this post.
Sorry for being so general and unclear in my post, I wasn't quite sure which portion of the code was the problem area. After looking over the code again, I noticed a stupid mistake. I set GridView's numColumns attribute to 5 in fragment_gallery.xml, but calculated the column width in GalleryFragment.java using private static final int NUM_COLUMNS = 4. I assume that this caused images to be displayed in a non-existent 5th column.

Categories

Resources