Im super confused between what is passed to the methods initially.
In ArrayAdapter getview method, What is the View and ViewGroup passed
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
....
}
List_item xml is
<LinearLayout 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:weightSum="1">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.09"
android:fontFamily="serif"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20sp"
android:textStyle="bold" />
....
</LinearLayout>
What is the ViewGroup passed in RecyclerView adapter here.
#Override
public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.number_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
NumberViewHolder viewHolder = new NumberViewHolder(view);
return viewHolder;
}
Number_list_item is
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="#+id/tv_item_number"
style="#style/TextAppearance.AppCompat.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:fontFamily="monospace"
android:textSize="42sp"
tools:text="#42" />
</FrameLayout>
What does the below line do exacty besides inflating the layout.
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately
View view = inflater.inflate(layoutIdForListItem, viewGroup,
shouldAttachToParentImmediately);
When you want to show any view on UI it must have some height and width. In a inflate method,
First parameter is a resource id of a view, which should inflate. In a case of Adapter, it should be item view which is going to be recycled.
Second parameter is a ViewGroup, generally parent view. Parent view must be a ViewGroup because ViewGroup contains child views not vice versa. In a case of ListView sometimes size(width) of an inflated view not adopted automatically depends on its parent.
For an example - If a ListView have a width match_parent then there is a possibility width of your inflated view less than its parent if you skipped this parameter.
Third parameter is used to decide whether you want to add your inflated view inside parent ViewGroup(2nd parameter). In a case of ListView, if you make it true then you will get RunTimeException (View already have a parent), this parameter should be true if you want to add new view inside parent view.
For an example - If I want to add View in my UI only after sudden action, then I will inflate a 'View' and add in a ViewGroup.
Related
I just created a list view with a custom view to create a country list for select
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/primary_light"
android:orientation="vertical"
tools:context=".RnActivity.RnView.RnUser.ActivitySignUpOptions">
<ListView
android:id="#+id/country_list_for_select_list_area"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/primary"
/>
</LinearLayout>
custom view
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/view_layout_country_list_item_country_icon_image"
android:layout_width="50dp"
android:layout_height="match_parent"
android:src="#drawable/gjh_logo_b"
/>
<TextView
android:id="#+id/view_layout_country_list_item_country_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="start|center_vertical"
android:layout_weight="1"
android:text="India"
android:textSize="18sp" />
<TextView
android:id="#+id/view_layout_country_list_item_country_code"
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center|center_vertical"
android:layout_gravity="right"
android:text="IN"
android:textSize="18sp"
/>
</LinearLayout>
In Activity
ListView country_list_for_select_list_area;
#Override
public void lodeControls() {
country_list_for_select_list_area=findViewById(R.id.country_list_for_select_list_area);
}
#Override
public void setEvents() {
}
RxAdopterCountry countryAdopter;
#Override
public void createAdopters() {
countryAdopter=new RxAdopterCountry(getActivity(),R.layout.view_layout_country_list_item, RsXtraCountryList.getInstance().getCountryList());
}
#Override
public void setData() {
country_list_for_select_list_area.setAdapter(countryAdopter);
}
In Adopter
private final ArrayList<RentCountry> countryList;
private Context context;
public RxAdopterCountry(#NonNull Context context, int resource, ArrayList<RentCountry> countryList) {
super(context, resource);
this.context=context;
this.countryList=countryList;
}
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if(convertView==null){
convertView= LayoutInflater.from(context).inflate(R.layout.view_layout_country_list_item, parent, false);
}
ImageView view_layout_country_list_item_country_icon_image=convertView.findViewById(R.id.view_layout_country_list_item_country_icon_image);
TextView view_layout_country_list_item_country_name=convertView.findViewById(R.id.view_layout_country_list_item_country_name);
TextView view_layout_country_list_item_country_code=convertView.findViewById(R.id.view_layout_country_list_item_country_code);
view_layout_country_list_item_country_name.setText(countryList.get(position).getName());
view_layout_country_list_item_country_code.setText(countryList.get(position).getCode());
view_layout_country_list_item_country_icon_image.setImageResource(countryList.get(position).getFlag_id());
return super.getView(position, convertView, parent);
}
i debugged the whole code and there are 250 items are coming in
private final ArrayList<RentCountry> countryList;
but list view is showing nothing
What I am doing wrong? I tried everything and debugged the whole code 10 times. yes I am getting the data in the ArrayList bu still noting is appearing in the list view.
Please help
The problem with your code is you are returning super.getView(position, convertView, parent) from getView while you should be returning the View you just created that is convertView .
For super constructor call you have to use super(context, resource, countryList) so that Adapter can return the size of list.
Change getView like below
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//...
return convertView;
}
Also you should be using RecyclerView now. ListView and GridView are legacy widgets for a long time . RecyclerView is much more flexible.
XML:
<androidx.recyclerview.widget.RecyclerView
android:visibility="visible"
android:id="#+id/itemshowRecylerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="#layout/singleitemforrecylerview"/>
Java Code:
itemshowRecylerview.setLayoutManager(new LinearLayoutManager(MainActivity.this));
itemshowRecylerview.setHasFixedSize(true);
Viewholder Code:
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.singleitemforrecylerview, null,false);
return new ItemDetailsAdapter.ViewHolder(view);
}
You need to change your custom adapter class, pass parent instead of null in your inflate method
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.singleitemforrecylerview, parent,false);
return new ItemDetailsAdapter.ViewHolder(view);
}
You have use this type of RecyclerView set orientation and layoutManager in RecyclerView and working code shown in below.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:spanCount="1">
</androidx.recyclerview.widget.RecyclerView>
recyclerView.setAdapter(yourAdapter);
I want to add CardView programmatically.
Here is my Main Activity XML Layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/linearLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical">
</LinearLayout>
Here is my CardViewTemplate (card_view_template.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cardViewTemplate"
android:layout_width="160dp"
android:layout_height="190dp"
android:layout_margin="10dp"
android:clickable="true"
android:foreground="?android:selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="This is a Card" />
</androidx.cardview.widget.CardView>
Here is my Java Code (MainActivity.java)
LayoutInflater inflater = getLayoutInflater();
ViewGroup parent = findViewById(R.id.linearLayout1);
inflater.inflate(R.layout.card_view_template, parent);
Everything works fine till here.
Now I want to add Card at certain position in my activity_main.xml as I am using multiple CardViews, I want to add Cards at certain position. Hence, instead of the above code, I tried this:
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.card_view_template, null);
ViewGroup parent = findViewById(R.id.linearLayout1);
parent.addView(view, 0);
But it does not inflate properly. Only the Text is visible, The Card does not seem to appear.
When dynamically adding views, we shouldn't inflate the View with null ViewGroup parent.
In this View view = inflater.inflate(R.layout.card_view_template, null); here parent is specified as null, this caused the problem.
Specify the parent to which the View will be attached to and only set attach to parent as false. This way Parent will be specified but not attached.
Hence first declare parent (root) and then create View and specify the parent (root) and set attach to parent (root) false
This is the correct statement
View view = inflater.inflate(R.layout.card_view_template, parent, false);
Hence the complete code will be:
LayoutInflater inflater = getLayoutInflater();
ViewGroup parent = findViewById(R.id.linearLayout1);
View view = inflater.inflate(R.layout.card_view_template, parent, false);
parent.addView(view, 0);
i suggest that you use directly the linear layout ,like:
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.card_view_template, null);
LinearLayout LL = findViewById(R.id.linearLayout1);
LL.addView(view,0);
I have a fragment class which uses Recycleview to show list of Text and Image.
How can I access Recycleview row items and set an custom text to any Textview or Hide the Desired Textview from fragment class.
This is my layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:paddingBottom="4dp"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:paddingTop="4dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />
<include
android:id="#+id/include_tag"
layout="#layout/row_item"/>
</FrameLayout>
and My row item layout is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res /android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent">
<TextView
android:id="#+id/flower_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:maxLines="1"
android:layout_centerInParent="true"
android:gravity="center_vertical|center_horizontal"
android:textAlignment="center"
android:textColor="#E91E63"
android:fontFamily="sans-serif-condensed"
android:text="Sagar Rawal"/>
<TextView
android:layout_marginTop="8dp"
android:id="#+id/flower_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:maxLines="3"
android:textColor="#673AB7"
android:text="This Text need to Be Change "/>
</RelativeLayout>
and my Fragment class i s
public View onCreateView(final LayoutInflater inflater, #Nullable final ViewGroup container, #Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.activity_main, container, false);
View test1View = view.findViewById(R.id.include_tag);
mhideText = (TextView) test1View.findViewById(R.id.flower_details);
mhideText.setVisibility(View.INVISIBLE);
return view;
But it doesn't work. and Textview is still Visible.
Please help. Thanks in advance.
You must have a custom ViewHolder which should extends RecyclerView.ViewHolder. In your ViewHolder you can link row item and you can access all views from your row layout.
Your custom ViewHolder looks like:
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView textView;
public MyViewHolder(TextView v) {
super(v);
textView = v;
//Note: To set custom text
textView.setText("My custom text");
//Note: To hide TextView remove comment from below line
//textView.setVisibility(View.GONE);
}
}
Above code shows sample ViewHolder as MyViewHolder where you can access your views.
If you are passing parent Layout to MyViewHolder instead of passing TextView then you can find child views using v.findViewById(R.id.xxx)
Your adapter should contain similar code as below:
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
...
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
In above code snippet, creating instance of MyViewHolder by passing the view TextView. You can pass parent layout in your case its RelativeLayout from your row layout.
Use this ViewHolder to take any actions on views like set custom text to TextView or you can hide TextView as per your requirements.
To refer full example you can follow the android documentation or click here.
To achieve communication between ViewHolder and fragment you can use Interface.
Thank you!
Try doing this :
rowview = inflater.inflate(R.layout.row_item, container, false);
mhideText = (TextView)rowview.findViewById(R.id.flower_details);
mhideText.setVisibility(View.INVISIBLE);
In my application I am experiencing the same sort of error as found here or here however the suggested solution of cleaning the Eclipse project isn't working for me. Specifically I have a custom ListView adapter that is attempting to load two TextViews from its layout file, the first TextView is found no problem but the second throws the ResourceNotFound exception and crashes the application.
Layout File
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/roomNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dp"
android:text="Room name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/roomNumText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/roomNameText"
android:layout_below="#+id/roomNameText"
android:text="Room number"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
Adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
m = new ViewHolder();
convertView = mInflater.inflate(R.layout.room_row, null);
convertView.setTag(m);
} else {
m = (ViewHolder) convertView.getTag();
}
m.name = (TextView) convertView.findViewById(R.id.roomNameText);
m.name.setText(rooms.get(position).getName());
m.roomNumber = (TextView) convertView.findViewById(R.id.roomNumText);
m.roomNumber.setText(rooms.get(position).getRoomNumber());
return convertView;
}
I have also tried editing R.java just to force Eclipse to regenerate the file but that also doesn't work. Really not sure what else to try since I have another adapter that is basically the same but for different data that works perfectly. Also ViewHolder is a static class that is just a container class for any views being accessed (have to use it according to coding style) in case anyone was wondering.
change
m.roomNumber.setText(rooms.get(position).getRoomNumber());
with
m.roomNumber.setText(String.valueOf(rooms.get(position).getRoomNumber()));
in your code you are using the setText(int stringId) which looks up inside R.string to retrive the stringId parameter . Also I would change your getView this way:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
m = new ViewHolder();
convertView = mInflater.inflate(R.layout.room_row, null);
m.name = (TextView) convertView.findViewById(R.id.roomNameText);
m.roomNumber = (TextView) convertView.findViewById(R.id.roomNumText);
convertView.setTag(m);
} else {
m = (ViewHolder) convertView.getTag();
}
m.name.setText(rooms.get(position).getName());
m.roomNumber.setText(String.valueOf(rooms.get(position).getRoomNumber()));
return convertView;
}