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);
Related
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);
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.
Alright so I have a fragment and I'd like to include, within its' xml file another layout which is programmatically inflated
Fragment:
public class zGoal_Fragment extends Fragment{
private LinearLayout todayView;
private View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.main_goal_view, container, false);
todayView = (LinearLayout)view.findViewById(R.id.todayView);
return view;
}
}
xml's file for fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/todayView"
>
</LinearLayout>
and xml layout I want included within the above xml programmatically:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/goalEditLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/test_color_two"
>
</LinearLayout>
I've tried a couple different methods all of which led to " on a null object reference" errors...
plz help :))
I suppose the solution which you are looking for are Android ViewStubs. These are dynamically inflated layouts.
For more information you could refer these :
How to use View Stub in android
https://developer.android.com/reference/android/view/ViewStub.html
However, if you don't wish to inflate one layout inside another during runtime, you could try this the include tag:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/todayView">
<include layout="#layout/your_layout_file_name"/>
</LinearLayout>
Have you tried something like this:
LinearLayout child = getLayoutInflater().inflate(R.layout.goalEditLayout, null);
todayView.addView(child);
Edit:
Inside onCreateView:
LinearLayout inflatedLayout = (LinearLayout) inflater.inflate(R.layout.goalEditLayout, todayView, true);
I have a ListView, titled myListView, that I would like to populate with 3 LinearLayout elements, titled layout1.xml, layout2.xml, and layout3.xml. All 3 LinearLayout elements are very similar; here is one of them:
<?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="horizontal" >
<TextView
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Los Angeles" />
<TextView
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="California" />
</LinearLayout>
My goal is to populate a the ListView (myListView) with these three LinearLayout elements. Does anyone know how I would go about doing this?
First of all, if all three linear layouts are alike, I suggest you to only use one.
Anyway, you have to use a custom adapter for your ListView. You create a class that extends ArrayAdapter for example. If you are not familiar with custom adapters, I suggest you take a look here.
In your getView method, you practically have to inflate a different *.xml, depending on your cell position. Thus:
#Override
puclic View getView (int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
switch (position) {
case 0: view = inflater.inflate(R.layout.my_layout_1, null, true);
//rest of my code
break;
case 1: view = inflater.inflate(R.layout.my_layout_2, null, true);
//rest of my code
break;
case 2: view = inflater.inflate(R.layout.my_layout_3, null, true);
//rest of my code
break;
default: break;
//rest of my code
return view;
}
As DDsix points out, you really should be using one layout that can handle whatever data you want, and then populate the fields using an adapter. If I had to guess, I'd bet the only difference between your layouts is the text for the city and state.
The documentation explains how to do this very well: http://developer.android.com/guide/topics/ui/layout/listview.html
Basically, you should create a private List<Location> mLocations; variable to hold your locations (Location would be a simple class you define with strings to hold city and state). Then, you can use the following in your adapter.
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = context.getLayoutInflater();
View view = inflater.inflate(R.layout.my_layout_1, parent);
Location location = mLocationList.get(position);
TextView cityView = view.findViewById(R.id.city_view);
TextView stateView = view.findViewById(R.id.state_view);
cityView.setText(location.getCity());
cityView.setText(location.getState());
return view;
}
I know how to customize the spinner. In my case it is a little bit different. I cannot modify my code more than I have now. Normally, I am able to make spinner that is reachable from all activities in my app.
I am trying to put icon along the textview in the spinner drop down.
Here the code I have;
Spinner.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="fill_parent" >
<Spinner
android:id="#+id/spinner"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:spinnerMode="dialog"
android:prompt="#string/language_prompt" />
spinner_row.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:addStatesFromChildren="true"
android:gravity="center_horizontal"
android:padding="5dp"
android:textColor="#FFFFFF"
android:textSize="17sp" >
</TextView>
<!-- Here I cannot use Relative layout. If I use it gives error like [java.lang.ClassCastException: android.widget.ImageView cannot be cast to android.widget.TextView]. Without layout I cannot implement ImageView. I am stuck here.
My activity class;
public class Base_Activity extends Activity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
//int flags = R.array.flags;
final Spinner spinner = (Spinner) menu.getItem(0).getActionView()
.findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.languages, R.layout.spinner_row);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
What I want is to make is custom Adapter so that I can put image along the textview in spinner list. I am not able to make normal way that I checked in many tutorials. I think it's because I am creating spinner in onCreateOptionsMenu() constructor.
u can take a look at this tutorial on AndroidHive
http://www.androidhive.info/2013/11/android-working-with-action-bar/
code snippet
// Spinner title navigation data
navSpinner = new ArrayList<SpinnerNavItem>();
navSpinner.add(new SpinnerNavItem("Local", R.drawable.ic_location));
navSpinner
.add(new SpinnerNavItem("My Places", R.drawable.ic_my_places));
navSpinner.add(new SpinnerNavItem("Checkins", R.drawable.ic_checkin));
navSpinner.add(new SpinnerNavItem("Latitude", R.drawable.ic_latitude));
// title drop down adapter
adapter = new TitleNavigationAdapter(getApplicationContext(),
navSpinner);
getView() and getDropDownView() from TitleNavigationAdapter
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item_title_navigation, null);
}
imgIcon = (ImageView) convertView.findViewById(R.id.imgIcon);
txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
imgIcon.setImageResource(spinnerNavItem.get(position).getIcon());
imgIcon.setVisibility(View.GONE);
txtTitle.setText(spinnerNavItem.get(position).getTitle());
return convertView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item_title_navigation, null);
}
imgIcon = (ImageView) convertView.findViewById(R.id.imgIcon);
txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
imgIcon.setImageResource(spinnerNavItem.get(position).getIcon());
txtTitle.setText(spinnerNavItem.get(position).getTitle());
return convertView;
}
Download that code and u r good to go