I am trying to create a icon and a short description below it. I have created a customised View class with a ImageView and a TextView and i integrated it with my xml file, now the imageView and the default text appears in the screen,i don't know how to change the text content of the textview or the source of the imageview.
MyView.java
package sda.jk;
public class MyView extends LinearLayout{
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
LayoutInflater li=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v= li.inflate(R.layout.myview, this);
}
}
myview.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" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_launcher"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="my view"/>
</LinearLayout>
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/sda.jk"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<sda.jk.MyView
android:id="#+id/myView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</sda.jk.MyView>
</LinearLayout>
Step-1 First assign id to image view and text view in myview. xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/myImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_launcher"
/>
<TextView
android:id="#+id/myText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="my view"/>
</LinearLayout>
Step-2
initialize your own view in oncreate method using
MyView mv = (MyView)findViewById(R.id.myView1);
step-3
initilize image view and text view using findViewById method of your own view
TextView textView = (TextView) mv.findViewById(R.id.myText);
ImageView imageView = (ImageView) mv.findViewById(R.id.myImage);
step-4
set text to text view using setText method
textView.setText("Sunil Kumar Sahoo");
set background image to image view using
imageView.setBackgroundResource(R.drawable.ic_launcher);
Your oncreate method will be like the following (from step-2 to step-4)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MyView mv = (MyView)findViewById(R.id.myView1);
TextView textView = (TextView) mv.findViewById(R.id.myText);
textView.setText("Sunil Kumar Sahoo");
ImageView imageView = (ImageView) mv.findViewById(R.id.myImage);
imageView.setBackgroundResource(R.drawable.ic_launcher);
}
You write a function in sda.jk.MyView for setting text. For changing text, just call the function with a string parameter
Class MyView extends LinearLayout
{
//...
public void setUserText(String str)
{
textview.setText(str);
}
//...
}
You can add custom attributes by writing a custom attr.xml and loading the attributes in your custom view's constructor. For a full example check this page
http://javawiki.sowas.com/doku.php?id=android:custom-view-attributes
There is a useful feature in TextView called compund drawables, which allows you to incorporate a drawable to be drawn above, below, left or right of your text.
use it like so:
<TextView
android:id="#+id/txt"
android:text="my compound drawable textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/xxxxx" />
you can use drawableBottom, drawableLeft etc.. as well.
this way you don't need to implement your own class.
For accessing individual elements from a View hierarchy, use the findViewById method. Refer to http://developer.android.com/reference/android/view/View.html#findViewById%28int%29
You would have to provide identifiers to your view elements in your XML thus:
<?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" >
<ImageView
android:id="#+id/imgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_launcher" />
<TextView
android:id="#+id/txtView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="my view" />
</LinearLayout>
and refer them from your custom view class thus:
ImageView imageView = (ImageView)v.findViewById(R.id.imgView);
TextView textView = (TextView)v.findViewById(R.id.txtView);
Typically, you would like to keep the views as instance variables (members) so that you can change them from other methods.
Related
This is my code for how each row looks.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="120dp"
android:id="#+id/recipe_container"
android:layout_margin="12dp"
android:background="#f1f1f1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/recipe_name_text_view"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:textSize="32sp"
android:text="DUMMY TEXT"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="#+id/recipe_time_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DUMMY TEXT"/>
<TextView
android:id="#+id/recipe_difficulty_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DUMMY TEXT"/>
</LinearLayout>
</LinearLayout>
<ImageView
android:id="#+id/recipe_thumbnail_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/sladice"/>
</LinearLayout>
As you can see I have margin set, if I check preview it is also shown.
I populated with inflate this listivew.
This is activity_sladice.xml.
<?xml version="1.0" encoding="utf-8"?>
<ListView 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/recipe_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.recepti.Sladice"
android:background="#color/colorPrimary">
</ListView>
Now each row is together, there is no spacing between left, right, bottom , top.
If I add margin or padding to listview it only works on the entire list, not on each row.
How to do it? I know I can add divider between each row but I also want spacing right and left.
This is getView method from custom adapter.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View recipeView = convertView;
ReceptThumbnail recipe = getItem(position);
// Inflate view if to be inflated
if (recipeView == null) {
recipeView = LayoutInflater.from(getContext()).inflate(R.layout.recipe_item, parent, false);
}
TextView recipeName = (TextView) recipeView.findViewById(R.id.recipe_name_text_view);
recipeName.setText(recipe.getName());
TextView recipeTime = (TextView) recipeView.findViewById(R.id.recipe_time_text_view);
recipeTime.setText(recipe.getTime());
TextView recipeDifficulty = (TextView) recipeView.findViewById(R.id.recipe_difficulty_text_view);
recipeDifficulty.setText(recipe.getDifficulty());
ImageView recipeImage = (ImageView) recipeView.findViewById(R.id.recipe_thumbnail_image_view);
recipeImage.setImageResource(recipe.getImageResourceID());
}
If you want to add margins to the ListView, add margns to the listview.
If you want to add margins to the items, add margins to the items.
It is simple.
However, I suggest you to use ConstraintLAyout. And RecyclerView instead of ListView.
Try using padding in the LinearLayout, and create another LinearLayout as a child of the original, and move the background attribute to it.
try setting margin programmatically in getView method using below method.
public static void setMarginLeft(View v, int left) {
ViewGroup.MarginLayoutParams params =
(ViewGroup.MarginLayoutParams)v.getLayoutParams();
params.setMargins(left, params.topMargin,
params.rightMargin, params.bottomMargin);
}
I want to create a class named TabView which extends RelativeLayout and it is inflated from xml that contains RelativeLayout. The thing is that it doesn't seem to work as I expected. Did I do something wrong in the constructor? I know layoutInflater.inflate returns View object but what do I have to make it equal to? Any advice is apprecited!
private class TabView extends RelativeLayout {
private int mIndex;
public TabView(Context context) {
super(context, null, R.attr.vpiTabPageIndicatorStyle);
LayoutInflater layoutInflater = LayoutInflater.from(context);
layoutInflater.inflate(R.layout.tabview_title_subtitle, null);
}
public int getIndex() {
return mIndex;
}
public void setTitle() {
TextView title = (TextView)findViewById(R.id.title);
title.setText("Followers");
}
public void setSubitle() {
TextView subtitle = (TextView)findViewById(R.id.subtitle);
subtitle.setText("435");
}
}
The following is tabview_title_subtitle.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" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title"
android:text="Subtitle"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
First, your layout should look like this:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title"
android:text="Subtitle"
android:textAppearance="?android:attr/textAppearanceMedium" />
</merge>
In other way you'll end up with RelativeLayout that contains another RelativeLayout
Second. Inflate it like this:
layoutInflater.inflate(R.layout.tabview_title_subtitle, this);
You can see the following blog for creating and using custom views in android.
And probably using
inflater.inflate(R.layout.view_color_options, this, true);
instead of
layoutInflater.inflate(R.layout.tabview_title_subtitle, null);
is what you need to do.
Use:
layoutInflater.inflate(R.layout.tabview_title_subtitle, this);
to actually add the inflated view to TabView(right now you just inflate it and immediately discard it). Also if you want to use your custom view in a xml layout then also implement the constructor that takes a Context and an AttributeSet.
Got my TextView in the xml:
<TextView
android:id="#+id/myTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left"
android:text="TextView"/>
I want to create multiple TextViews but i want to look them the same as this.
So I tried:
TextView newTextView = new TextView(this);
newTextView.setLayoutParams(myTextView.getLayoutParams());
I think this should get all the layout parameters from myTextView straigthlghly(?) from the xml, and pass them to newTextView to set them.
My problem is: Nothing happens. It does not take effect, why?
here's a sample project which shows that it works.
you can see that it works by looking at the preview of the visual editor , which looks different than what is shown at runtime.
i think that your mistake was that you didn't set 0px (or 0dp, zero is still zero) for the weighted views.
main.xml (layout) :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="#+id/container">
<TextView android:id="#+id/textView1" android:layout_width="wrap_content"
android:layout_height="0px" android:text="TextView1"
android:layout_weight="1" android:background="#ffff0000" />
<TextView android:id="#+id/textView2" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="TextView2"
android:background="#ff00ff00" />
</LinearLayout>
TestActivity.java :
public class TestActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView tv1=(TextView)findViewById(R.id.textView1);
final TextView tv2=(TextView)findViewById(R.id.textView2);
final LayoutParams layoutParams=tv1.getLayoutParams();
tv2.setLayoutParams(layoutParams);
// adding textView programatically:
final TextView tv3=new TextView(this);
tv3.setText("textView3");
tv3.setBackgroundColor(0xff0000ff);
tv3.setLayoutParams(layoutParams);
final ViewGroup root=(ViewGroup)findViewById(R.id.container);
root.addView(tv3);
}
}
I'm trying to get a reference to an ImageView object and for whatever reason, it keeps coming back as null.
XML:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="6dip">
<ImageView android:id="#+id/application_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/label" android:text="Application Name" />
<CheckBox android:id="#+id/check" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" />
</LinearLayout>
Java:
ImageView img = (ImageView) v.findViewById(R.id.application_icon);
I don't feel like I'm doing anything wrong yet my img var always comes back as null. What's wrong with this picture?
Sat's answer is correct, i.e., you need a proper layout, but setContentView() is not the only way to reference a View. You can use a LayoutInflater to inflate a parent layout of the View (even if it is not shown) and use that newly inflated layout to reference the View.
public class MyActivity extends Activity {
Context context;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
// the rest of yout code
private void someCallback() {
LayoutInflater inflater = (LayoutInflater) context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout ll = (LinearLayout) inflater.inflate(R.layout.iconLayout, null);
ImageView img = (ImageView) ll.findViewById(R.id.application_icon);
// you can do whatever you need with the img (get the Bitmap, maybe?)
The only change you need to your xml file is to add an ID to the parent layout, so you can use it with the LayoutInflater:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="iconLayout"
<!-- all the rest of your layout -->
<ImageView android:id="#+id/application_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<!-- all the rest of your layout -->
</LinearLayout>
When you are referencing the imageView , make sure that you are using the proper layout, i.e. setContentView(R.layout.yourIntendedXmlLayout);
That xml should contain your imageView. Then you can refer to your imageView.
use
ImageView img = (ImageView)findViewById(R.id.application_icon);
How to use a layout as empty view for a listview when the adapter has zero elements?
setEmptyView is not working with this code :
public class ZeroItemListActivity extends Activity {
private ArrayList<String> listItems=new ArrayList<String>();
private ListView mMyListView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMyListView=(ListView) findViewById(R.id.MyListView);
mMyListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,listItems));
LayoutInflater inflator=getLayoutInflater();
View emptyView=inflator.inflate(R.layout.empty_list_item, null);
//Empty view is set here
mMyListView.setEmptyView(emptyView);
}
public void addItem(View v){
listItems.add("list Item");
mMyListView.invalidate();
}
}
Layouts used : empty_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<Button android:id="#+id/Button01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Empty List,Click to add items"></Button>
</LinearLayout>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="#string/hello" />
<ListView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/MyListView"></ListView>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/AddItemsButton"
android:text="Add Items" android:onClick="addItem"></Button>
</LinearLayout>
The easiest way to get this done is to put the empty view in the main.xml layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<ListView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/MyListView">
</ListView>
<!-- empty view -->
<LinearLayout android:id="#+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button android:id="#+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Empty List,Click to add items">
</Button>
</LinearLayout>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/AddItemsButton"
android:text="Add Items"
android:onClick="addItem"></Button>
</LinearLayout>
Then, in your code, set your empty view like this:
mMyListView.setEmptyView(findViewById(R.id.emptyView));
The reason your code isn't working is that the ListView and Empty view need to be in the same view heirarchy. And your call to inflate pass null as the parent so they are in different heirarchies.
The Android Dev tutorial for List Activity covers this topic:
http://developer.android.com/reference/android/app/ListActivity.html
Basically have your class extend ListActivity. Set your list id to #id/android:listand the "empty view" id to #id/android:emptyin the same XML layout.
Hope this helps :)
When, inflating the view, you have to set the view parent to be part of the Layout hierarchy rather than pass null in some cases.
Replace
View emptyView = inflator.inflate(R.layout.empty_list_item, null);
with
View emptyView = inflator.inflate(R.layout.empty_list_item, (ViewGroup) mMyListView.getParent());
then you set the empty view as you did before with.
mMyListView.setEmptyView(findViewById(R.id.emptyView));