I am trying to write an Android Wear application. For now I've got a TextView and would like to set the text programmatically.
private TextView mTextView;
private TextView text;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_my);
final WatchViewStub stub = (WatchViewStub)findViewById(R.id.watch_view_stub);
text = (TextView)findViewById(R.id.text);
stub.setOnLayoutInflatedListener((stub -> {
mTextView = (TextView)stub.findViewById(R.id.text);
}};
text.setText("test");
}
When trying to run the application like that I get a nullpointerexception at
text.setText("test");
That led me to assume that the TextView "text" was not found. Normally on Android phone applications it is just fine to call the
text = (TextView)findViewById(R.id.text);
Directly after
setContentView();
But now there are things like the WatchViewStub and the setOnLayoutInflatedListener. Maybe there's something I've overseen?
However, how do I specify my TextView correctly on the Android Wear platform?
Edit:
activity_my.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
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/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="#layout/rect_activity_my"
app:roundLayout="#layout/round_activity_my"
tools:context=".MyActivity"
tools:deviceIds="wear">
</android.support.wearable.view.WatchViewStub>
rect_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:orientation="vertical"
tools:context=".MyActivity"
tools:deviceIds="wear_square">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/text"
android:textSize="30sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
round_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
tools:context=".MyActivity"
tools:deviceIds="wear_round">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/text"
android:textSize="30sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
According to code from your Activity:
private TextView mTextView;
private TextView text;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_my);
final WatchViewStub stub = (WatchViewStub)findViewById(R.id.watch_view_stub);
text = (TextView)findViewById(R.id.text);
stub.setOnLayoutInflatedListener((stub -> {
mTextView = (TextView)stub.findViewById(R.id.text);
}};
text.setText("test");
}
Why do you have two TextViews? You have only one either in your rect_activity: or round_activity: layouts.
You have to understand how WatchViewStub works. You cannot access views from your rect/round layouts right after setContentView because they are not inflated yet. Like you did - you can access your views only in OnLayoutInflatedListener listener callback.
You have tried to find your mTextView inside this callback - which is the way you should do it.
What is wrong?
You should remove following lines:
text = (TextView)findViewById(R.id.text);
and this one: (it also causes your NullPointerException)
text.setText("test");
and keep only the mTextView field.
What should you do?
Add following like right after mTextView = (TextView)stub.findViewById(R.id.text);:
mTextView.setText("test");
It must be incide the OnLayoutInflatedListener.
Your final code should look like:
private TextView mTextView;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_my);
final WatchViewStub stub = (WatchViewStub)findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener((stub -> {
mTextView = (TextView)stub.findViewById(R.id.text);
mTextView.setText("test");
}};
}
You do not have TextView in activity_my.xml
text = (TextView)findViewById(R.id.text);
if rect_activity.xml and round_activity.xml are for different activities then you need to create new activities and call setContentView for those xml
Only after that you can use the views in your code.
Instead of adding an OnLayoutInflatedListener you can extend InsetActivity and set your content view in InsetActivity.onReadyForContent():
import android.support.wearable.activity.InsetActivity;
public class MainActivity extends InsetActivity {
...
#Override
public void onReadyForContent() {
setContentView(R.layout.activity_main);
someTextField = (TextView) findViewById(R.id.some_field);
Related
I have an XML file that has a TextView, and I want to change its gravity from the main activity.
I used this code in the main activity:
// I just coppied the related codes
TextView tvValue;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvValue = findViewById(R.id.tv_value);
// the tv_value id is from the (word_item.xml) file
}
private void OnClickFunc(View view) {
tvValue.setGravity(Gravity.RIGHT);
}
and the problem is that I get a NullPointerException error on a null object reference.
I know that I should somehow connect the xml file with the main activity.
word_item.xml file:
<?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="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/tv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Word" />
</LinearLayout>
Thank you and I appreciate your help.
if you havent included the word_item.xml in your activity_main.xml then the error is obvious
so this is how you can include another file in any xml file in android
<include layout="#layout/word_item.xml" />
then things ll work as you expect
Try to first inflate the other layout as follows the initialize the view
LayoutInflater inflater = LayoutInflater.from(MainActivity.this); final View v = inflater.inflate(R.layout.word_item, null);
Then
Textview tvValue = findViewById(R.id.tv_value); private void OnClickFunc() { tvValue.setGravity(Gravity.RIGHT);
Where did you initialize textView variable?? Variable must be initialize after setContentView in OnCreate method in Activity.
I have a ViewFlipper in my main_activity and there are included activities (pages).
<ViewFlipper
android:id="#+id/vf"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/include_news"
layout="#layout/activity_news"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="#+id/include_latest_posts"
layout="#layout/activity_latest_posts"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="#+id/include_categories"
layout="#layout/activity_categories"
android:layout_width="match_parent"
android:layout_height="match_parent" />
...
</ViewFlipper>
The acitvities (pages) have their own java files.
I tried to modify a textView from there:
public class latest_posts extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View myView = findViewById(R.id.include_latest_posts);
TextView tv = myView.findViewById(R.id.list);
tv.setText("HELLO");
}
}
But when I ran the app, nothing happened. How can I access the Views from the java file of page-acitvity?
I also tried to create an onClick function for a Button in an included activity. It worked in the MainActivity's java file where the VievFlipper is. How can I create an onClick function in the included activity's java file?
Try like this
private TextView _textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_latest_posts);
_textView = (TextView) findViewById(R.id.myTv);
_textView.setText("It works!");
}
I am trying to understand how to add views programatically (with java) in Android applications. I created a simple layout (below) to practice that but I struggle to solve the following error:
java.lang.IllegalStateException: Could not find method addingView() in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'button'
Screenshot from the app:
My XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.android.view_create_test_1.MainActivity">
<LinearLayout
android:id="#+id/top"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:background="#555555">
</LinearLayout>
<RelativeLayout
android:id="#+id/bottom"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#116677">
<Button
android:text="Add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
android:layout_centerInParent="true"
android:onClick="addingView"/>
</RelativeLayout>
</LinearLayout>
My JAVA:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void addingView (){
LinearLayout top = (LinearLayout) findViewById(R.id.top);
LinearLayout newLayout = new LinearLayout (this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
newLayout.setLayoutParams(new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, 50));
top.addView(newLayout,params);
}
}
Please help me out how to solve the error. Thanks
Your method should come like this
public void addingView (View view){
LinearLayout top = (LinearLayout) findViewById(R.id.top);
LinearLayout newLayout = new LinearLayout (this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
newLayout.setLayoutParams(new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, 50));
top.addView(newLayout,params);
}
When you specify an onclick method in Xml, it must contain the corresponding method in your Activity. However you must include the correct parameters. THe View parameter is required.
Change your addingView method declaration to:
public void addingView (View v){
Your error is however of changeColor(View), which i assume else where, you have done the same thing to the changeColor declaration. Add the View parameter to this method also
I'm using the Android Studio standard template "Navigation Drawer Activity" which contains the content_main.xml layout.
On this layout is my textView which I want to change the text from my MainActivity.java.
I tried following but nothing changes:
LayoutInflater inflater = (LayoutInflater)this.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.content_main, null);
TextView txt = (TextView)view.findViewById(R.id.txt_head);
txt.setText("sdfsdf");
content_main.xml:
<?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:id="#+id/relativelayout_for_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.w4ter.ledcontroldesign.MainActivity"
tools:showIn="#layout/app_bar_main"
android:orientation="vertical"
android:paddingTop="10dp">
<TextView
android:text="Presets"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/TextAppearance.AppCompat.Headline"
android:id="#+id/txt_head" />
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="#61000000" />
</LinearLayout>
there is no need of LayoutInflater. Simply use:
TextView textView = (TextView) findViewById(R.id.txt_head);
texView.setText("Hello");
Hope this helps.
You just need to access the TextView component the normal way. With that template the content_main.xml is included inside the main layout, so you sould do as follows in your main activity (maybe inside the onCreate method or wherever you need):
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView txt = (TextView)view.findViewById(R.id.txt_head);
txt.setText("sdfsdf");
}
//...
}
Assuming that you have a app_bar_main.xml inside the main layout wich contains the content_main.xml. In the end everything is accessible from the main activity directly since the layouts are included in the main layout.
Hope it helps!
I am creating an extremely simple Android application to serve as a proof of concept and a reference for an application I will create in the future.
My goal is to create a ListView, each item containing a TextView and a Button that, when pressed, makes a Toast pop up displaying the content of the TextView.
Here is my code and xml:
main.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">
<ListView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/mainListView1"/>
</LinearLayout>
entry.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:gravity="center_vertical"
android:orientation="horizontal"
android:id="#+id/entryLayout"
>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/entryTextView1"
android:padding="10dp"
android:textSize="25sp"/>
<ImageButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#android:drawable/ic_menu_close_clear_cancel"
android:id="#+id/entryImageButton"
/>
</LinearLayout>
MainActivity.Class
public class MainActivity extends Activity{
/* Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Set main.xml as user interface layout
setContentView(R.layout.main);
String[] companies = new String[] { "Test1", "Test2", "Test3",
"Test4", "Test4", "Test6", "Test7", "Test8", "Test9", "Test10"};
ArrayList<LinearLayout> views = new ArrayList<LinearLayout>();
for(int x=0; x!= companies.length-1; x++){
LinearLayout layout = (LinearLayout) findViewById(R.id.entryLayout);
TextView text = (TextView) layout.getChildAt(0);
text.setText(companies[x]);
ImageButton button = (ImageButton) layout.getChildAt(1);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
LinearLayout layout = (LinearLayout) v.getParent();
TextView view = (TextView) layout.getChildAt(0);
Toast.makeText(MainActivity.this,view.getText(), Toast.LENGTH_SHORT).show();
}
});
views.add(layout);
}
ListView listView = (ListView) findViewById(R.id.mainListView1);
for(LinearLayout layout: views){
listView.addView(layout);
}
}
I get an Kin the line
TextView text = (TextView) layout.getChildAt(0);
And for the life of me I can't figure out why. This is likely due to my lack of knowledge to how certain functions in the API work.
Your immediate issue is that findViewById looks in the layout you've inflated with setContentView() and since the Views you are trying to inflate aren't in that layout, they return null.
So this line returns null
LinearLayout layout = (LinearLayout) findViewById(R.id.entryLayout);
which causes a NPE at this line as you've noticed
TextView text = (TextView) layout.getChildAt(0);
because layout is null.
The bigger issue is the way you are going about using your ListView. Since you want to use a custom layout for the rows, you should be using a custom Adapter and inflate the appropriate layout there . You can then utilize Adapter's getView() method to set the data in each row as needed.
This tutorial can help you get started on that.
You also may want to watch Google I/O World of ListView
ListView Docs