NullPointerException when accessing constructor - java

I feel like either I'm missing a vital point in OOP, or my constructor is wrong. I keep getting a null pointer exception when creating my object.
The logcat is saying that its coming from the first line of the '// default constructor'.
Here is the code for my class:
package com.chriswahlfeldt.homeworkapp;
import android.app.Activity;
import android.view.View;
import android.widget.EditText;
public class MyHomework extends Activity {
private EditText title, description;
private View homeworkView, activityView;
// default constructor
public MyHomework() {
homeworkView = getLayoutInflater().inflate(R.layout.add_homework, null);
activityView = getLayoutInflater().inflate(R.layout.activity_my, null);
title = (EditText) homeworkView.findViewById(R.id.classTitleET);
title.setText("");
description = (EditText) homeworkView.findViewById(R.id.descriptionET);
title.setText("");
}
public View getContentView_activity_my() { return activityView; }
public View getContentView_add_homework() { return homeworkView; }
public String getTitleTxt() { return title.getText().toString(); }
public String getDescriptionTxt() { return description.getText().toString(); }
public void setTitleTxt(String thatString) { title.setText(thatString); }
public void setDescriptionTxt(String thatString) { title.setText(thatString); }
}
And here is where it is used:
package com.chriswahlfeldt.homeworkapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MyActivity extends Activity
{
private MyHomework hW = new MyHomework();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(hW.getContentView_activity_my());
final Button addHWBtn = (Button) findViewById(R.id.HWBtn);
addHWBtn.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
setContentView(hW.getContentView_add_homework());
}
});
}
}
.xml file: activity_my.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MyActivity"
android:id="#+id/mainRelLayout" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/HWBtn"
android:textSize="25sp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:hint="+Homework"/>
</RelativeLayout>
.xml file: add_homework.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:alpha=".8">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/classTitleET"
android:layout_gravity="top"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:capitalize="sentences"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="10dp"
android:hint="Class Title"
android:textSize="20sp" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:ems="8"
android:id="#+id/descriptionET"
android:layout_below="#+id/classTitleET"
android:layout_alignLeft="#+id/classTitleET"
android:layout_alignStart="#+id/classTitleET"
android:layout_alignRight="#+id/classTitleET"
android:layout_alignEnd="#+id/classTitleET"
android:hint="Homework Description"
android:textSize="20sp"
android:height="120dp"
android:gravity="top" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/createBtn"
android:hint="Create"
android:textSize="20sp"
android:layout_below="#+id/descriptionET"
android:layout_alignLeft="#+id/descriptionET"
android:layout_alignStart="#+id/descriptionET"
android:layout_alignRight="#+id/descriptionET"
android:layout_alignEnd="#+id/descriptionET" />
</RelativeLayout>
Thx!

yout can't call getLayoutInflater() directly , you need to call it on an instance of the LayoutInflater class.
try this
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
homeworkView = inflater.inflate(R.layout.add_homework, null);
you can replace context with "this" if you are calling this inan activity

It's a bad practice to put the code inside a constructor for activities. You can put in the OnCreate method.
If you need this instance really.
You can do the following
public class MyHomework extends Activity {
private EditText title, description;
private View homeworkView, activityView;
private static MyHomework instance;
#Override
protected void onCreate(Bundle savedInstanceState) {
instance = this;
}
public static MyHomework getActivity() {
return instance;
}
}
public class MyActivity extends Activity
{
private MyHomework hW = MyHomework.getActivity();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.....
}
}

You cannot call activity methods or use the activity as a Context before onCreate() in the activity lifecycle. Instance initialization including constructor is too early. As a consequence, you rarely need to use an explicit constructor with activities.
Never instantiate activity classes with new. Related to the point above: such objects are not really good for anything since they are not properly initialized as activities and their activity lifecycle methods such as onCreate() are not invoked.
It looks like your MyHomework should not be an activity at all:
Remove the `extends Activity``
Pass in a Context as an argument to methods that need it. For example,
public MyHomework(Context context) {
homeworkView = LayoutInflater.from(context).inflate(...)
Invocation from MyActivity onCreate() (not member variable init, too early):
homework = new MyHomework(this)

Related

How to stop fragments from being recreated in fragment transaction

I have an activity with multiple steps, each step being a fragment transaction with an edittext box, with a next/back button to navigate and initiate sending the users input data. I want to be able to move throughout the fragments with the text in each box staying static. I can move back no problem, but as soon as I click next the next fragment is recreated and everything is lost.
I tried:
using a dummy view in onCreateView
refetching the string in onCreate
setRetainInstance(true); in the constructor
Using a viewpager has other complications regarding receiving data which I was not able to solve despite many here attempting to help, so I have no choice but to use fragment transactions in my app.
main/FormActivity.java
package com.loopbreakr.formproject;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
public class FormActivity extends AppCompatActivity implements PageOne.ExitFormInteractionListener{
//DECLARE COMPONENTS
private FrameLayout fragmentContainer;
private Button backToMain;
private Button startForm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//FIND COMPONENTS IN XML
setContentView(R.layout.activity_form);
fragmentContainer = findViewById(R.id.frame_layout);
backToMain = findViewById(R.id.return_button);
startForm = findViewById(R.id.start_button);
//SET LISTENERS/INTENTS FOR BUTTONS
backToMain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
startForm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openFragments();
}
});
}
private void openFragments() {
PageOne fragment1 = PageOne.newInstance();
FragmentManager fragmentManager =getSupportFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
beginTransaction.addToBackStack(null);
beginTransaction.add(R.id.frame_layout,fragment1,"PageOne_tag");
beginTransaction.commit();
}
#Override
public void onFragmentInteraction(String answerOneText) {
}
}
One of my fragments PageOne.java
package com.loopbreakr.formproject;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class PageOne extends Fragment {
View restored;
private static final String SAVED = "text";
private String savedText;
private String answerOneString;
private EditText answerOne;
private ExitFormInteractionListener mListener;
public PageOne() {
setRetainInstance(true);
}
public static PageOne newInstance() {
PageOne fragment = new PageOne();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
savedText = getArguments().getString(SAVED);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
if(restored == null){
restored = inflater.inflate(R.layout.fragment_page_one, container, false);
}
answerOne = restored.findViewById(R.id.answer_one);
Button exitForm = restored.findViewById(R.id.exit_form);
Button goNextTwo = restored.findViewById(R.id.gonext_two);
exitForm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
returnToDesc();
}
});
goNextTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
answerOneString = answerOne.getText().toString();
sendToTwo(answerOneString);
openSecondFragment();
}
});
return restored;
}
private void sendToTwo(String answerOneText) {
if(mListener != null){
mListener.onFragmentInteraction(answerOneText);
}
}
private void openSecondFragment() {
PageTwo fragment2 = PageTwo.newInstance(answerOneString);
FragmentTransaction fragTransition = getFragmentManager().beginTransaction();
fragTransition.replace(R.id.frame_layout, fragment2,"PageTwo_TAG");
fragTransition.addToBackStack(null);
fragTransition.commit();
}
private void returnToDesc(){
FragmentManager fragTransBack = getFragmentManager();
fragTransBack.popBackStack();
}
public interface ExitFormInteractionListener{
void onFragmentInteraction(String answerOneText);
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
if (context instanceof ExitFormInteractionListener) {
mListener = (ExitFormInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
activity_form.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FormActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="32dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
</LinearLayout>
<TextView
android:id="#+id/activity_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="#string/activity_title"
android:textSize="32sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:stateListAnimator="#null"/>
<Button
android:id="#+id/return_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginBottom="8dp"
android:text="#string/return_text"
app:layout_constraintBottom_toTopOf="#+id/linearLayout"
app:layout_constraintStart_toStartOf="parent"
android:stateListAnimator="#null"/>
<Button
android:id="#+id/start_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:text="#string/start_text"
app:layout_constraintBottom_toTopOf="#+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
android:stateListAnimator="#null"/>
<FrameLayout
android:id="#+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/linearLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
activity_page_one.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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clickable="true"
tools:context=".PageOne"
android:focusable="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<TextView
android:id="#+id/activity_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="#string/activity_title"
android:textSize="32sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<Button
android:id="#+id/exit_form"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginBottom="8dp"
android:text="#string/back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:stateListAnimator="#null"/>
<Button
android:id="#+id/gonext_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:text="#string/next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:stateListAnimator="#null"/>
<EditText
android:id="#+id/answer_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:gravity="start|top"
android:hint="#string/answer_one_hint"
android:inputType="textMultiLine|textAutoCorrect"
android:maxLines="4"
android:minLines="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/activity_name"
android:stateListAnimator="#null"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
Thanks.

setContentView() not working as expected - why?

I am making an app an tried using setContentView in Android Studio when i used it the layout changed but the app is still using the first java it is not changing the code is given bellow
i tried changing the file up i also tried creating a new empty file but it didnt work
:-
import androidx.appcompat.app.AppCompatActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;
public class MainActivity extends AppCompatActivity {
private Handler mHandler = new Handler();
private int progress = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ProgressBar progressBar = findViewById(R.id.progressBar);
new Thread(new Runnable() {
#Override
public void run() {
while(progress < 100) {
progress++;
android.os.SystemClock.sleep(25);
mHandler.post(new Runnable() {
#Override
public void run() {
progressBar.setProgress(progress);
}
});
}
mHandler.post(new Runnable() {
#Override
public void run() {
setContentView(R.layout.activity_on_boarding);
}
});
}
}).start();
}
}
xml:-
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="187dp"
android:layout_height="141dp"
android:contentDescription="#string/logo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.137"
app:srcCompat="#drawable/logo" />
<TextView
android:id="#+id/title"
android:layout_width="307dp"
android:layout_height="210dp"
android:text="#string/title"
android:textColor="#000000"
android:textSize="40sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.52"
tools:fontFamily="casual"
/>
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="300dp"
android:layout_height="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.795" />
</androidx.constraintlayout.widget.ConstraintLayout>
second java:-
package com.thebetterside.wallex;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.os.Bundle;
public class OnBoarding extends AppCompatActivity {
private Button go = findViewById(R.id.go);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_on_boarding);
go.setOnClickListener(
new Button.OnClickListener(){
#Override
public void onClick(View v) {
setContentView(R.layout.activity_name);
}
}
);
}
}
2nd xml:-
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".OnBoarding">
<Button
android:id="#+id/go"
android:layout_width="351dp"
android:layout_height="44dp"
android:background="#drawable/rounded_corner_peach"
android:text="#string/go"
android:textColor="#000046"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.504"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.945" />
</androidx.constraintlayout.widget.ConstraintLayout>
You want to do startActivity(this, OnBoarding.class) instead of calling the setContentView()
setContentView() sets the layout for the current activity, it does not start the second one.
And judging from the code you posted, you want to transfer control to your other java file (OnBoarding.java) and that must be done by starting that activity explicitly.
EDIT: in your case, it'll most probably be MainActivity.this.startActivity(MainActivity.this, OnBoarding.class) because just this will point to the thread, instead of the enclosing Context/Activity

Timetable android application not working

I have made an android application, and its getting successfully compiled without any errors. But when I run app in my android phone, then it does not show the desired output.
This is my MainActivity.java:
package wahab.com.timetabledemo;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.support.v7.widget.Toolbar;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupUIViews();
initToolbar();
}
private void setupUIViews(){
toolbar = (Toolbar)findViewById(R.id.ToolbarMain);
listView = (ListView)findViewById(R.id.lvMain);
}
private void initToolbar(){
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("TimeTable App");
}
private void setupListView(){
String[] title = getResources().getStringArray(R.array.Main);
String[] description = getResources().getStringArray(R.array.Description);
SimpleAdaptor simpleAdaptor = new SimpleAdaptor(this, title, description);
listView.setAdapter(simpleAdaptor);
}
public class SimpleAdaptor extends BaseAdapter{
private Context mContext;
private LayoutInflater layoutInflater;
private TextView title, description;
private String[] titleArray;
private String[] descriptionArray;
private ImageView imageView;
public SimpleAdaptor(Context context, String[] title, String[] description){
mContext = context;
titleArray = title;
descriptionArray = description;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return titleArray.length;
}
#Override
public Object getItem(int i) {
return titleArray[i];
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null){
view = layoutInflater.inflate(R.layout.main_activity_single_item,null);
}
title = (TextView)view.findViewById(R.id.tvMain);
description = (TextView)view.findViewById(R.id.tvDescription);
imageView = (ImageView)view.findViewById((R.id.ivMain));
title.setText(titleArray[i]);
description.setText(descriptionArray[i]);
if(titleArray[i].equalsIgnoreCase("Timetable")){
imageView.setImageResource(R.drawable.timetable);
}
else if(titleArray[i].equalsIgnoreCase("Subjects")){
imageView.setImageResource(R.drawable.book);
}
else if(titleArray[i].equalsIgnoreCase("Faculty")){
imageView.setImageResource(R.drawable.contact);
}
else{
imageView.setImageResource(R.drawable.settings);
}
return view;
}
}
}
The given above is a error free code.
This is my activity_main.xml:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="wahab.com.timetabledemo.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/ToolbarMain"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="#color/colorPrimary"
app:titleTextColor="#color/white">
</android.support.v7.widget.Toolbar>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lvMain"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:dividerHeight="10dp"
android:layout_below="#+id/ToolbarMain"
android:divider="#null">
</ListView>
</RelativeLayout>
In my activity_main.xml, I have used a RelativeLayout in which I have defined a Toolbar and a ListView. A ListView is defined so that I can add different list of operation.
This is my main_activity_single_item.xml:
<android.support.v7.widget.CardView android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#color/colorAccent"
android:elevation="4dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="80dp"
android:layout_height="105dp"
android:id="#+id/ivMain"
android:layout_marginLeft="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvMain"
android:textStyle="bold"
android:text="Timetable"
android:layout_marginTop="6dp"
android:layout_marginLeft="6dp"
android:layout_toRightOf="#+id/ivMain"
android:textSize="25sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvDescription"
android:text="description"
android:layout_marginLeft="6dp"
android:layout_marginTop="3dp"
android:layout_below="#+id/tvMain"
android:layout_toRightOf="#+id/ivMain"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvClick"
android:textSize="12sp"
android:text="click to know more"
android:layout_marginTop="6dp"
android:layout_alignParentRight="true"
android:layout_below="#+id/tvDescription"
android:layout_alignBottom="#+id/ivMain"/>
</RelativeLayout>
In this above xml file, I have created a CardView which will consist of an ImageView and 3 TextView, which is placed using a RelativeLayout.
So, my code is getting compiled properly and my app is also running but am not getting the desired output.
You need to call setupListView() in onCreate to display the list
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupUIViews();
initToolbar();
setupListView(); // to display list
^^^^^^^^^^
}

Function calling wrong class

I am trying to use an intent to start two different classes in which I change either the text size or text colour of an entered message. Starting these classes is triggered by two different button push events in android studio. However, only the TextSize class is being started no matter what button I push and I cannot see the reason why. Below I have the problem activities class code and xml code
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
public static final String EXTRAA_MESSAGE ="message2";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void changeText(View v){
EditText messageView = (EditText)findViewById(R.id.message);
String messageText = messageView.getText().toString();
Intent result = new Intent(this, TextSize.class);
result.putExtra("message",messageText);
startActivity(result);
}
public void changeColour(View v){
EditText messageView = (EditText)findViewById(R.id.message);
String messageText = messageView.getText().toString();
Intent result = new Intent(this, ColourChange.class);
result.putExtra("message",messageText);
startActivity(result);
}
My XML File
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView2"
android:layout_alignParentTop="true"
android:layout_marginTop="14dp" />
<EditText
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:ems="10"
android:layout_below="#+id/textView2"
android:layout_alignParentStart="true" />
<Button
android:text="Change Colour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Colour"
android:onClick="changeColour"
android:layout_centerVertical="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="36dp"
android:onClick="changeText"
android:text="Change Text Size"
android:layout_alignBaseline="#+id/Colour"
android:layout_alignBottom="#+id/Colour"
android:layout_alignParentEnd="true"
android:layout_marginEnd="33dp"
android:id="#+id/TextSize" />
In Android just implements the OnClickListener for you when you define the android:onClick="someMethod" attribute.
you can implemented just different way.
Button btnColour = (Button) findViewById(R.id.Colour);
btnColour.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// call your method here
changeColour(v);
}
});
// your method code
public void changeColour(View v) {
// your method code
}
As You doing
check your xml file that have you define context with parent layout or not
tools:context="com.example.YourActivity"
// com.example.YourActivity should be your activity with package name

setText() on a textView coming from a subClass in Android

First I'm a beginner in Android development !
In my app, I include a library that help me to create card UI.
In this library, you have a basic layout where there is a Title, a description and a thumbnails but you can create and inflate a custom layout for having a better filled card.
What I want to do is to change the text of a TextView coming from the sub Class, which is linked to the sub Layout. But everytime I try to invoke the setText method from the MainActivity, I get a NullPointerexception.
There is my sub Class:
import it.gmariotti.cardslib.library.internal.Card;
import it.gmariotti.cardslib.library.internal.Card.OnCardClickListener;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
public class CustomCardAccueil extends Card{
public TextView TitreExtensionAccueil;
public TextView DateSortieAccueil;
public TextView NombreCarteAccueil;
public TextView DescriptionExtensionAccueil;
public TextView RareteCarteAccueil;
public TextView DetailExtensionAccueil;
public CustomCardAccueil(Context context) {
this(context, R.layout.accueil_mycard_inner_content);
}
/**
*
* #param context
* #param innerLayout
*/
public CustomCardAccueil(Context context, int innerLayout) {
super(context, innerLayout);
init();
}
/**
* Init
*/
private void init(){
//No Header
//Set a OnClickListener listener
setOnClickListener(new OnCardClickListener() {
#Override
public void onClick(Card card, View view) {
Toast.makeText(getContext(), "Click Listener card=", Toast.LENGTH_LONG).show();
}
});
}
#Override
public void setupInnerViewElements(ViewGroup parent, View view) {
TitreExtensionAccueil = (TextView) parent.findViewById(R.id.TitreExtensionAccueil);
}
}
My Layout where there is the TextView that I want to change:
<?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/TitreExtensionAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/DateSortieAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/TitreExtensionAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/NombreCarteAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/DateSortieAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/DescriptionExtensionAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/NombreCarteAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/RareteCarteAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/DescriptionExtensionAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/DetailExtensionAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/RareteCarteAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
And there is how I try to change the content of TextView in my MainActivity, in the OnCreate:
CustomCardAccueil.TitreExtensionAccueil.setText("Test");
There is also the error I get in the logcat of the crash:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText.setText(java.lang.CharSequence)' on a null object reference
I don't understand the error because the object is initiated (correct me if I'm wrong).
Also if I try to change the text from the sub class (CustomCardAccueil), it's a success, but I need to do it through my MainActivity.
Any help is appreciated, thanks in advance !
You need to initialize the class with something like:
CustomCardAccueil myCard = new CustomCardAccueil(mContext, R.mylayout);
The context you can get from your activity class using something like MyActivity.this or getApplicationContext(). Then you can use methods such as the class' setText:
myCard.setText("blah")
Your TitreExtensionAccueil is said to be null when you are trying to set the text.
You may want to point out where are CustomCardAccueil.TitreExtensionAccueil.setText("Test"); is called for better respond to your question.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText.setText(java.lang.CharSequence)' on a null object reference
shows that you invoked setText() on a null object, so did you initialize CustomCardAccueil.TitreExtensionAccueil and how?
your problem is or you are not using the proper instance for the class CustomCardAccueil, as you declared and initialized the TextView through it, So, even you have to make an instance from the class or to make the TextView declared as static variable, but make sure you run the method called setupInnerViewElements() before trying to set the TextView value.
UPDATE:
to get the current window view through some layout:
View global_view = getWindow().getDecorView(); // use that in the MainActivity to get the view
then, pass that view to your method setupInnerViewElements() and simply create the view with it not with ViewGroup:
in your MainActivity:
CustomCardAccueil mCard = new CustomCardAccueil(getApplicationContext(), R.layout.accueil_mycard_inner_content);
mCard.setupInnerViewElements(parent, global_view);
in your setupInnerViewElements() method:
#Override
public void setupInnerViewElements(ViewGroup parent, View view) {
TitreExtensionAccueil = (TextView) view.findViewById(R.id.TitreExtensionAccueil);
}
I've found the answer by looking at the card library and his setTitle Library (I don't know why I've not thinked to this sooner !)
In my CustomCardAccueil class, I've created a String as this:
protected static String titreExtension;
Here is the getter and setter methods:
public String getTitreExtension() {
return titreExtension;
}
public static void setTitreExtension(String titre) {
titreExtension = titre;
}
Again in CustomCardAccueil, in setupInnerViewElements method, I've put this:
TitreExtensionAccueil = (TextView) view.findViewById(R.id.TitreExtensionAccueil);
TitreExtensionAccueil.setText(titreExtension);
And in my MainActivity I simply call my setter with:
CustomCardAccueil.setTitreExtension("test du setTitreExtension");
Simply as this !

Categories