I have create class that extend View, i`m trying to layout.addView(somthing) in layout, not exception is trowed.
layout
<RelativeLayout
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" >
</RelativeLayout>
class
public class Navigator extends View {
Context context;
RelativeLayout layout = (RelativeLayout) findViewById(R.layout.navigator);
public Navigator(Context context) {
super(context);
this.context = context;
}
TextView tab1 = new TextView(context);
tab1.setText("blah");
PROBLEM-> layout.addView(tab1);
}
Are you adding your extended view to an Activity?
Because you are modifying your view but I can't see where are you attaching your "Navigator" view.
Another thing is that your RelativeLayout declared on the XML has no ID, so you will never find a RelativeLayout with R.id.navigator id.
Related
I have a TextView, which I need to be centered horizontally and vertically inside a square. To do this, I have put it inside a RelativeLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#fff"
>
<TextView
android:id="#+id/centered_text_view_text"
android:layout_centerInParent="true"
android:text="test"
android:background="#00ff00"
android:textColor="#000"
android:textSize="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
I instantiate the RelativeLayout with a LayoutInflater and then call the layout method on the RelativeLayout to position it where I need it.
LayoutInflater inflater = Helpers.getInflater();
containerLayout = (RelativeLayout) inflater.inflate(R.layout.centered_text_view, null);
textView = (TextView) containerLayout.findViewById(R.id.centered_text_view_text);
... (later in the code)
containerLayout.layout(dayLeft, weekTop, dayRight, weekBottom);
My problem is that the TextView is not visible. I can see the white background for the RelativeLayout, but neither the text nor the background for the TextView.
I have also tried getting rid of the RelativeLayout and calling the layout method on the TextView. I haven't been able to get this to work, however, because the text is only horizontally, and not vertically, aligned after I set the gravity on the TextView.
First - Custom views should extend some sort of View.class. The class to extend should be whatever your root view is in your xml.
Second - You are keeping a reference to containerLayout (root view) which is redundant. This class is the root view.
Replace containerLayout with this or just removing entirely:
textView = (TextView) findViewById(R.id.centered_text_view_text);
Third - I can't say how you are inflating is wrong, but I have never done it like that.
Instead of calling layout on a containerLayout, try inflating with the inflate() method. (You get access to this when extending a sub class of View)
inflate(getContext(), R.layout.view_user_tag, this);
Notice how I am setting this as the root, and using the inflater from the view class.
Your class may look like something like this:
public static class TextInLinear extends RelativeLayout {
public TextView textView;
//region default constructers
public void TextInLinear(Context context){
this(context, null);
}
public void TextInLinear(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public void TextInLinear(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if(!isInEditMode()) init();
}
//endregion
private void init(){
inflate(getContext(), R.layout.view_user_tag, this);
textView = (TextView) this.findViewById(R.id.centered_text_view_text);
}
/* more methods. i.e. setText(), getText() or whatever */
}
I have created a custom textview class and i am trying to inflate it in my main xml. Here is my code :-
public class CustomTextView extends TextView{
public CustomTextView(Context context) {
super(context);
LayoutInflater li = LayoutInflater.from(context);
TextView view = (TextView) li.inflate(R.layout.customtextview,null);
view.setBackgroundColor(Color.RED);
}
}
customtextview.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:text="sgfiughbjkh"
android:id="#+id/customtext"
android:layout_height="match_parent" >
</TextView>
and in my main activity xml, i have only one linear layout :-
LinearLayout main = (LinearLayout)findViewById(R.id.mainView);
CustomTextView cus = new CustomTextView(this);
main.addView(cus);
I know if i extend it to linear layout instead of textview and add a lienarlayout as parent and in it that textview, it works.
But the problem is that i want to inflate an xml with only a textview and inflate it and the above code is not working.
Please suggest
How do inflate a xml containing only one textview using layout inflator ?
// inflate text view
TextView textView = (TextView) getLayoutInflater().inflate(R.layout.customtextview, null);
// add it to your view
// in your condition, we will add it to Linear Layout
LinearLayout main = (LinearLayout)findViewById(R.id.mainView);
main.addView(textView);
It's old and 2 years later, I ran into the same issue.
You cannot extend from a View and inflate from a layout. The view needs to be wrapped by a ViewGroup . Read Understanding Android's LayoutInflater.inflate()
I came up with 2 solutions , either :
1. in your class CustomTextView , you set programmatically all the properties . Don't inflate anything. Good luck with conversion from resources dimen.xml
2. In your Activity , inflate the Textview
LinearLayout main = (LinearLayout)findViewById(R.id.mainView);
TextView textView = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.customtextview, null);
// you might need as well to set the layout params again
// LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
// textView.setLayoutParams(params);
main.addView(textView);
A bit late but maybe it will help people.
first and like Pratik goyal said you need to declare your CustomTextView and not a TextView
<com.example.CustomTextView
android:id="#+id/customTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Then in your CustomTextView class you need to had those lines (Constructor):
public FontFitTextView(final Context context) {
super(context);
}
public FontFitTextView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
And last (correct me if i'm wrong people), but you can't inflate a customView into a TextView.
TextView textView = (TextView) getLayoutInflater().inflate(R.layout.customtextview, null);
rather you need to put your R.layout.customTextView into a customTextView
CustomTextView customTxtView = (CustomTextView) getLayoutInflater().inflate(R.layout.customlayout, null);
And now that i'm writing this down i don't think it's possible to inflate only a TextView. If you want to inflate R.layout.customlayout you need to have at least a layout (Linear,Relative etc...) that wrap your customTextView
Something like this
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.yourpakagename.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView"
android:layout_centerInParent="true"
android:includeFontPadding="false"
android:text="13" />
</RelativeLayout>
You can find all of your custom created views under heading "Custom & Library Views" in the Graphical interface of Eclipse.
If your CustomTextView is in the package "com.example" than you can define your custom component as :
<com.example.CustomTextView
android:id="#+id/customTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
I wanted to use a TabHost inside an existing TabHost/TabActivity. So I wanted to get rid of the Activity class and just implement a viewgroup class inheriting from TabHost. However, it seems like it is not possible to use TabHost without a corresponding Activity class - the TabHost and it's contents just won't show up when displaying the extended class.
I used the TabHost class and added the linear layout containing the tabs and content containers with the appropriate IDs (android:id/tabs and android:id/tabcontent) from xml.
public class EmitterView : TabHost, TabHost.ITabContentFactory
{
public EmitterView(Context context) :
base(context)
{
Initialize();
}
public EmitterView(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize();
}
private void Initialize()
{
// construct the TAB Host
LayoutInflater inflater = (LayoutInflater)
this.Context.GetSystemService(Context.LayoutInflaterService);
View view = inflater.Inflate(AndroidFilterEditor.Resource.Layout.EmitterTabHost, null);
this.AddView(view);
this.Setup();
// Create Tabs
TabSpec emitter = this.NewTabSpec("Emitter");
emitter.SetIndicator("Emitter", Resources.GetDrawable(AndroidFilterEditor.Resource.Drawable.ic_tab_artists));
//Intent emitterIntent = new Intent(this.Context, typeof(EmitterActivity));
emitter.SetContent(this);
this.AddTab(emitter);
this.Invalidate();
}
public View CreateTabContent(string tag)
{
EmitterContentView view = new EmitterContentView(this.Context);
return view;
}
}
The Layout definition:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"/>
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Any idea if this could be possible? This is Mono for Android btw, so the code is in C# obviously.
You can use ActivityGroup to host more than one activity in it and assign tabhost to each of them. Though it gets complicated and is not encouraged. I will suggest you to use Fragments instead of tabhost inside another tabhost.
I'm struggling with a problem for a few days already and couldn't find solution to my problem so far.
I have two classes:
- StartActivity extends Activity
- TimeGraphView extends SurfaceView
What I want to achieve is to add dynamically buttons from within TimeGraphView to another view (LinearLayout).
To do so wanted to get that LinearLayout inside TimeGraphView with findViewById() but it returns null, and it should because I call it in TimeGraphView not in root element where I used setContentView();
So my question is how can I add button dynamically from custom view level to another view.
And my code:
public class StartActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.time_graph);
LinearLayout layout = (LinearLayout) this.findViewById(R.id.TimeGraphLayout);
//here I can add button but it's not what I want
}
}
and ...
public class TimeGraphView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
public TimeGraphView(Context context) {
super(context);
}
public TimeGraphView(Context context, AttributeSet set) {
super(context, set);
}
public TimeGraphView(Context context, AttributeSet set, int arg) {
super(context, set, arg);
}
public void run() {
while (run) {
if (something) {
LinearLayout layout = (LinearLayout) findViewById(R.id.TimeGraphLayout);
if (layout != null) {
Button button = new Button(context);
button.setText(text);
layout.addView(button);
} else {
Log.e("TimeGraphView", "TimeGraphLayout is null");
//and "layout" is always null and that's the problem ;(
}
}
}
}
}
... and my XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/TimeGraphRootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<HorizontalScrollViewa
android:id="#+id/TimeGraphPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/TimeGraphLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</HorizontalScrollView>
<my.package.TimeGraphView
android:id="#+id/TimeGraphChart"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
You cannot use it in that way. If you add a root element Linearlayout and reference that in addition it might work. If you want to get the TimeGraphLayout class though:
TimeGraphView layout = (TimeGraphView) findViewById(R.id.TimeGraphLayout);
setContentView(layout);
The original way you did it will not work because TimeGraphView is not a LinearLayout
In my Activity i have:
DrawView which is a Custom Relative Layout.
This RelativeLayout should exist of a Custom Navigationbar and a Custom GridView
The Custom NavigationBar is added here to the DrawView:
final LayoutInflater factory = getLayoutInflater();
final View textEntryView = factory.inflate(R.layout.multiplechoice, null);
com.lernapp.src.Views.NavigationBarTest navigation = (com.lernapp.src.Views.NavigationBarTest)textEntryView.findViewById(R.id.navigationbar);
RelativeLayout parent = (RelativeLayout)navigation.getParent();
parent.removeAllViews();
drawView.addView(navigation);
i wanted to do something similar with the GridView..
I dont get it, my CustomGridView is always null, why is this!?
MyCustomGridView grid = (MyCustomGridView)findViewById(R.id.gridview);
xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.lernapp.src.Views.MyCustomGridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:listSelector="#android:color/transparent"
android:numColumns="auto_fit"
android:columnWidth="160dp"/>
</LinearLayout>
CustomGridView:
public class MyCustomGridView extends GridView implements OnItemClickListener{
private Listener mListener;
public MyCustomGridView(Context context, AttributeSet attrs) {
super(context, attrs);
setOnItemClickListener(this);
}
public void onItemClick(AdapterView parent, View v, int position, long id) {
if (mListener != null) {
mListener.onClick(position);
}
}
public void setListener(Listener l){
mListener = l;
}
public interface Listener{
void onClick(int position);
}
}
EDIT:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int height = this.getWindowManager().getDefaultDisplay().getHeight();
int width = this.getWindowManager().getDefaultDisplay().getWidth();
MyCustomGridView grid = (MyCustomGridView)findViewById(R.id.gridview);
DrawView drawView = new DrawView(this, dragFieldText, targetFieldText, height, width, grid);
final LayoutInflater factory = getLayoutInflater();
final View textEntryView = factory.inflate(R.layout.multiplechoice, null);
com.lernapp.src.Views.NavigationBarTest navigation = (com.lernapp.src.Views.NavigationBarTest)textEntryView.findViewById(R.id.navigationbar);
RelativeLayout parent = (RelativeLayout)navigation.getParent();
parent.removeAllViews();
drawView.addView(navigation);
setContentView(drawView);
}
Add this line to your onCreate and all will be good:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.the_name_of_the_layout_for_this_activity);
And to be really clear, its
setContentView(R.layout.the_name_of_the_layout_for_this_activity);
You should add to the onCreate, and it must be added BEFORE you try and do findViewById().
You have 2 options
you use findViewById. The view you're looking for MUST be "on the screen" by having used setContentView(). THere's no other way around it, that's what the function findViewById is for.
If you cannot use setContentView() because you want to programatically set this view and it is not in an XML you want to set for some reason, you have to INFLATE the view and then do your magic with it, and then you can use setContentView() as you wish. Examples of how to do this are easy, but check out the manual and some random example
As Heinrisch said you need to call setContentView before using findViewById().
Why dont you add your custom Relative Layout to your layout xml? Usually you dont need to inflate Views by yourself.
<com.lernapp.src.Views.DrawView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.lernapp.src.Views.MyCustomGridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:columnWidth="160dp"
android:listSelector="#android:color/transparent"
android:numColumns="auto_fit" />
</com.lernapp.src.Views.DrawView>