I've seen similar questions to mine here, but none of the solutions have helped (I've tried many).
So I have a fragment, which I'm create an instance of both in my main activity and in another activity. The fragment has methods to change various TextViews, and everything works great when I call those methods from my main activity. However, when I try to do the same in my other activity, I keep getting a null pointer exception that the textView isn't found. Here is the relevant code:
activity where it doesn't work:
TextView p1n;
TextView p2n;
TextView p1s;
TextView p2s;
ScoreFragment SF;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tic_tac_toe);
SF = new ScoreFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.frag_frame_ttt, SF);
ft.commit();
Intent intent = getIntent();
Log.d(jl, intent.getStringExtra(P1_NAME_KEY));
if (intent != null) {
if (intent.getStringExtra(P1_NAME_KEY) != null && p1n != null) {
SF.setp1name(intent.getStringExtra(P1_NAME_KEY));
}
if (intent.getStringExtra(P2_NAME_KEY) != null && p2n != null) {
SF.setp2name(intent.getStringExtra(P2_NAME_KEY));
}
if (p1s != null) {
SF.setp1score(intent.getIntExtra(P1_SCORE_KEY, 0));
}
if (p2s != null) {
SF.setp2score(intent.getIntExtra(P2_SCORE_KEY, 0));
}
Log.d(jl, Integer.toString(intent.getIntExtra(P2_SCORE_KEY, 0)));
}
Since p1n, p2n, p1s, and p2s are always null, nothing happens.
Here is the frame layout i'm trying to put the fragment in,
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/frag_frame_ttt"
android:paddingBottom="20dp"
/>
and here is my relevant fragment code:
...
TextView p1name;
TextView p2name;
TextView p1score;
TextView p2score;
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_score, container, false);
p1name = (TextView) v.findViewById(R.id.p1_name);
p2name = (TextView) v.findViewById(R.id.p2_name);
p1score = (TextView) v.findViewById(R.id.p1_score);
p2score = (TextView) v.findViewById(R.id.p2_score);
Log.d(jl, "onCreateView successful");
return v;
}
public void setp1name(String name) {
p1name.setText(name);
}
public void setp2name(String name) {
p2name.setText(name);
}
public void setp1score(int score) {
p1score.setText(Integer.toString(score));
}
public void setp2score(int score) {
p2score.setText(Integer.toString(score));
}
and the relevant fragment xml:
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Player 1"
android:id="#+id/p1_name"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" : " />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:id="#+id/p1_score"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Player 2"
android:id="#+id/p2_name"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" : " />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:id="#+id/p2_score"/>
</LinearLayout>
</LinearLayout>
So after doing some debugging I am quite certain that the issue has to do with the findViewById method in onCreateView() not finding anything, but I've tried moving where I findViewById (such as in each method where the text is being set), but it still hasn't worked.
Any help would be much appreciated.
Got it!
Aside from my stupid bug in my activity where I only set the text if the textview variables (the ones I never set) aren't null...
I had to move all of the code pertaining to my fragment (except for the initialize and the add / commit) from onCreate to onStart. Guess I was trying to preform actions on these textviews before the fragment actually inflated(? sorry I'm new to android, this may be incorrect).
Related
I'm trying to use saved instance state methods to save the contents of a text view but it keeps returning a null pointer exception (LogCat: Attempt to Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference). The app works fine on launch, but for some reason the textView is null when the activity is destroyed and restored (IE when I rotate the screen)
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
//other fields
public static final int MAX_SEATS = 6;
int numSeats;
String resultText = "0";
static final String KEY_RESULT_STRING = "result string";
static final String KEY_NUM_SEATS = "numberSeats";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState != null){
resultText = savedInstanceState.getString(KEY_RESULT_STRING);
numSeats = savedInstanceState.getInt(KEY_NUM_SEATS);
displayResult();
}
//variables for widgets
mTextView = findViewById(R.id.textView);
//next two lines display "where would you like to sit" on screen
TextView mIntro = findViewById(R.id.intro);
mIntro.setText(R.string.introduction);
EditText mNumRequestedSeats = findViewById(R.id.seatAmountNumberEdit);
Button reserve = (Button) findViewById(R.id.submit_button);
reserve.setOnClickListener(view -> {
//EditText mNumRequestedSeats = findViewById(R.id.seatAmountNumberEdit);
try{
String requestedSeats = mNumRequestedSeats.getText().toString();
numSeats = Integer.parseInt(requestedSeats);
}
catch(NumberFormatException wrongSeat){
Toast.makeText(getApplicationContext(),R.string.wrongFormatError, Toast.LENGTH_SHORT).show();
numSeats = 0;
}
displayResult();
});
}
private void displayResult(){
if (numSeats > 6){
resultText = "Please dial 123-456-7890 for parties larger than 6";
}else {
resultText = "Thank you for your reservation.";
}
mTextView.setText(resultText);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState){
savedInstanceState.putString(KEY_RESULT_STRING, resultText);
savedInstanceState.putInt(KEY_NUM_SEATS, numSeats);
super.onSaveInstanceState(savedInstanceState);
}
}
and here is the layout file:
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/numberOfSeats"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/intro"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="#string/introduction"
android:textAlignment="center"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textColor="#color/dark_blue"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints">
</TextView>
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:contentDescription="#string/waiter_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/submit_button"
app:srcCompat="#drawable/waiter" />
<Button
android:id="#+id/submit_button"
style="#style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:backgroundTint="#color/button_grey"
android:text="#string/mainActivitySubmit"
android:textColor="#color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/intro"
tools:ignore="MissingConstraints" />
<TextView
android:id="#+id/seatAmountPrompt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="130dp"
android:text="#string/seatAmount"
android:textColor="#color/dark_blue"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView" />
<EditText
android:id="#+id/seatAmountNumberEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="306dp"
android:ems="3"
android:inputType="number"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/seatAmountPrompt" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/seatAmountNumberEdit" />
</androidx.constraintlayout.widget.ConstraintLayout>
I've tried initializing the textView with a default String value but it still comes back with a null pointer when I change orientation. What am I doing wrong?
Note: I know it's probably easier to use something like textFreeze in the layout XML but this is a springboard into a more complicated project so I want to learn to implement saved bundles properly.
Please refer to: https://developer.android.com/guide/components/activities/activity-lifecycle.html#java
You are missing the public void onRestoreInstanceState(Bundle savedInstanceState) function.
UPDATED ANSWER
I finally got a chance to look over the code properly. The issue is that you have placed findViewById() code after you call displayResult(). The TextView components have not been initialized/ hooked up yet, so they're still null. The reason onRestoreState() is working is because it is being called after the Activity view has been created.
Relocate this code after everything else inside onCreateView().
if(savedInstanceState != null){
resultText = savedInstanceState.getString(KEY_RESULT_STRING);
numSeats = savedInstanceState.getInt(KEY_NUM_SEATS);
displayResult();
}
To add to the excellent point made by #Sovathna Hong, the reason it works is because the non-overwritten method is then being called. It is important that we understand that the onRestoreState() is being called in both cases, it is simply being auto called when we don't explicitly override it in case of if(savedInstanceState != null).
So I have the following fuction inside an adapter class. I want my Toast to print the text of a TextView when a certain icon is clicked but turns out I'm unable to get that TextView inside of my onClick function.
public TitleParentViewHolder onCreateParentViewHolder(ViewGroup viewGroup) {
View view = inflater.inflate(R.layout.list_routines, viewGroup, false);
ImageView playIcon = (ImageView) view.findViewById(R.id.playRoutine);
playIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView rutNameView = (TextView) v.findViewById(R.id.parentTitle);
String rutName = rutNameView.getText().toString(); //THIS crashes because rutNameView is null
Toast.makeText(v.getContext(), rutName + " was played",
Toast.LENGTH_LONG).show();
}
});
return new TitleParentViewHolder(view);
}
I've tried defining rutName outside of teh onClick but its value changes so that doesn't make sense (it's first initalized as "" and then assigned a value that I get from an API).
The text I'm trying to get is the one inside of the TextView with id parentTitle in a CardView. I have several of these cardViews. I don't know if it's relevant but here's the code.
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/playRoutine"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_margin="8dp"
android:src="#drawable/play_gris"
android:visibility="visible" />
<TextView
android:id="#+id/parentTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="16dp"
android:textSize="20dp"
android:textStyle="bold" />
<ImageButton
android:id="#+id/expandArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_margin="8dp"
android:src="#drawable/expande_de_lista"
android:visibility="visible" />
</RelativeLayout>
</android.support.v7.widget.CardView>
Do this -
public TitleParentViewHolder onCreateParentViewHolder(ViewGroup viewGroup) {
View view = inflater.inflate(R.layout.list_routines, viewGroup, false);
ImageView playIcon = (ImageView) view.findViewById(R.id.playRoutine);
TextView rutNameView = (TextView) view.findViewById(R.id.parentTitle);
playIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String rutName = rutNameView.getText().toString();
Toast.makeText(v.getContext(), rutName + " was played",
Toast.LENGTH_LONG).show();
}
});
return new TitleParentViewHolder(view);
}
Write below declaration code before playIcon.setOnClickListener
TextView rutNameView = (TextView) v.findViewById(R.id.parentTitle);
I'm trying to create a 'favourites' view dynamically in android by recording whether the user has favoured a specific sound bite in my app and then inserting the sub view into a parent view with the appropriate info about a particular soundbite. Essentially, creating a custom playlist of soundbites.
I'm having problems with the layoutInflator though. If I add more than one sub view into my parent view, only the last sub view added will have the appropriate parameters entered, whereas the rest have the default values from the sub view xml layout.
Here is my java code displaying the general idea behind adding subviews:
LayoutInflater l = getLayoutInflater();
LinearLayout ll = (LinearLayout)findViewById(R.id.favlist);
if(getIntent().getExtras()!=null)
{
Bundle extras = getIntent().getExtras();
Intent test = getIntent();
if(test.hasExtra("favThunder")){
String favValues = extras.getString("favThunder");
View v = l.inflate(R.layout.sublayout, null);
ll.addView(v);
ImageView favImage = (ImageView)findViewById(R.id.favimage);
favImage.setImageResource(R.drawable.thundercats);
TextView tv = (TextView) findViewById(R.id.favtitle);
tv.setText(R.string.thundercats);
TextView tvClicks = (TextView) findViewById(R.id.timesplayed);
tvClicks.setText("Times played: " + favValues);
favImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mp.isPlaying()) {
mp.stop();
}
mp = MediaPlayer.create(getApplicationContext(), R.raw.thunder);
mp.start();
}
});
}
if(test.hasExtra("favSkeletor")){
String favValues = extras.getString("favSkeletor");
View v = l.inflate(R.layout.sublayout, null);
ll.addView(v);
ImageView favImage = (ImageView)findViewById(R.id.favimage);
favImage.setImageResource(R.drawable.skeletor);
TextView tv = (TextView) findViewById(R.id.favtitle);
tv.setText(R.string.skeletor);
TextView tvClicks = (TextView) findViewById(R.id.timesplayed);
tvClicks.setText("Times played: "+favValues);
favImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mp.isPlaying()) {
mp.stop();
}
mp = MediaPlayer.create(getApplicationContext(), R.raw.skeletor);
mp.start();
}
});
}
And here is my sub view and parent view xml respectively
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="#+id/favimage"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="200dp"
android:src="#drawable/thundercats"
android:scaleType="fitCenter"/>
<LinearLayout
android:layout_weight="0.5"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/favtitle"
android:layout_weight="0.4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A TEST TITLE"/>
<TextView
android:layout_weight="0.3"
android:id="#+id/timesplayed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Times played: Heck!"/>
</LinearLayout>
</LinearLayout>
Parent xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context="com.example.markohare.ohareb00716779_cw1.MainActivity"
>
<LinearLayout
android:id="#+id/favlist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
</LinearLayout>
</ScrollView>
What am I doing wrong? Is my subview too complex or is there something wrong in my java code?
Thanks
I have a custom view adapter with four buttons and a title that populate a ListView.
When a user clicks one of those buttons, I want to retrieve the title associated with that specific adapter.
So far I have tried retrieving the parent and getting the textView but that does not return the correct title.
So...how would I get the specific title affiliated to the adapter that has the button the user clicked on?
I'd be happy to clarify if you need more information.
Here is the layout of the adapter.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/fragment_student_home_classTitle_textView"
android:paddingTop="20dp"
android:layout_toLeftOf="#+id/linearLayout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="#+id/linearLayout">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_grades"
android:background="#ffff130c" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment_student_home_grades_imageButton"
android:src="#drawable/ic_grades_512"
android:background="#00000000" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_notification_textEdit"
android:background="#ffff130c" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment_student_home_notification_imageButton"
android:src="#drawable/ic_bell_512"
android:background="#00000000" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_homework"
android:background="#ffff130c" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment_student_home_homework_imageButton"
android:src="#drawable/ic_foundation_book_bookmark_simple_black_512x512"
android:contentDescription="#string/homework_notification_icon"
android:background="#00000000" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/fragment_student_home_attendance"
android:background="#ffff130c" />
<ImageButton
android:layout_width="42dp"
android:layout_height="40dp"
android:id="#+id/fragment_student_home_attendance_imageButton"
android:src="#drawable/ic_attendance"
android:contentDescription="#string/homework_notification_icon"
android:background="#00000000" />
</LinearLayout>
</LinearLayout>
And here is the adapter where I implemented the onClick
public class ClassAdapter extends ArrayAdapter<SchoolClass> implements View.OnClickListener{
private SchoolClass aClass;
public ClassAdapter(Context context, int resource, ArrayList<SchoolClass> objects) {
super(context, resource, objects);
}
public SchoolClass getSchoolClass(){
return this.aClass;
}
public void setSchoolClass(SchoolClass schoolClass){
this.aClass = schoolClass;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.classes_adapter, null);
}
aClass = getItem(position);
if(aClass != null){
TextView title = (TextView) v.findViewById(R.id.fragment_student_home_classTitle_textView);
if(title != null){
title.setText(aClass.getTitle());
}
setSchoolClass(aClass);
}
//set buttons
ImageButton notificationsButton = (ImageButton) v.findViewById(R.id.fragment_student_home_notification_imageButton);
ImageButton gradesButton = (ImageButton) v.findViewById(R.id.fragment_student_home_grades_imageButton);
ImageButton attendanceButton = (ImageButton) v.findViewById(R.id.fragment_student_home_attendance_imageButton);
ImageButton homeworkButton = (ImageButton) v.findViewById(R.id.fragment_student_home_homework_imageButton);
notificationsButton.setOnClickListener(this);
gradesButton.setOnClickListener(this);
attendanceButton.setOnClickListener(this);
homeworkButton.setOnClickListener(this);
return v;
}
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), ClassActivity.class);
View parent = (View) v.getRootView();
//v.getParent() returns null when I look for the textView
TextView title = (TextView) parent.findViewById(R.id.fragment_student_home_classTitle_textView);
System.out.println("\n\n title: " + title.getText().toString() + " \n\n");
intent.putExtra("__CLASS_NAME__", title.getText().toString());
It populates a list view and if I were to click on fragment_student_home_attendance_imageButton I would want to get the fragment_student_home_classTitle_textView associated with that ClassAdapter.
Just give a idea to you, hope this can help to fix the problem :)
#Override
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
// ....
ImageButton notificationsButton = (ImageButton) v.findViewById(R.id.fragment_student_home_notification_imageButton);
notificationsButton.setTag(R.id.fragment_student_home_notification_imageButton);
// ....
return v;
}
#Override
public void onClick(View v) {
if(v!=null && v.getTag()!=null && v.getTag()==R.id.fragment_student_home_notification_imageButton){
// do something you like
}
}
Ok nevermind, I got it.
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), ClassActivity.class);
//It's the parent of the parent OF THE parent where
//the textView lies in my layout.
View parent = (View) v.getParent().getParent().getParent();
TextView title = (TextView) parent.findViewById(R.id.fragment_student_home_classTitle_textView);
System.out.println("\n\n title: " + title.getText().toString() + " \n\n");
intent.putExtra("__CLASS_NAME__", title.getText().toString());
If there is a better way to get this solution, as it seems like a head on approach to the problem, I welcome any comments!
I have a fragment with an XML layout file. in it I have an 2 clickable ImageViews.
for each ImageView I set an onClick method for example: android:onClick="commentFragmentRemoveOnClick".
In the FragmentActivity (The Activity no the Fragment) I defined it this way:
public void commentFragmentRemoveOnClick(View v)
{
}
No this Fragment is of type CommentFragment and it has a public void getFragmentTag()method
to get it's tag that I save in earlier time. I need to get an instance of the fragment in which the image was clicked to get it's tag.
I tried:
((CommentFragment)v).getParentFragment().getFragmentTag();
and:
((CommentFragment)v).getParent().getFragmentTag();
but eclipse gives me error on both of them, how is this done properly?
To make it more clear this is my CommentFragment:
public class CommentFragment extends Fragment {
private final static String TAG = CommentFragment.class.getSimpleName();
private String fragmentTag;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.comment_fragment_layout,
container, false);
Bundle bundle = getArguments();
String text = bundle.getString("comment");
String fullUser = bundle.getString("user");
String user = fullUser.substring(0, fullUser.indexOf("#"));
String at = bundle.getString("at");
TextView tvCmment = (TextView) rootView.findViewById(R.id.tvComment);
TextView tvUser = (TextView) rootView.findViewById(R.id.tvUser);
TextView tvAt = (TextView) rootView.findViewById(R.id.tvDate);
tvCmment.setText(text);
tvUser.setText(user);
tvAt.setText(at);
return rootView;
}
public void setText(String item)
{
TextView view = (TextView) getView().findViewById(R.id.tvComment);
view.setText(item);
}
public void setFragmentTag(String tag)
{
this.fragmentTag = tag;
}
public String getFragmentTag()
{
return this.fragmentTag;
}
}
and the layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llCommentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#drawable/try2">
<TextView
android:id="#+id/tvUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/tvComment"
android:layout_alignParentTop="true"
android:background="#color/my_gray"
android:text="demo"
android:textStyle="bold"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:textColor="#color/my_even_darker_gray" />
<TextView
android:id="#+id/tvComment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/tvDate"
android:padding="5dp"
android:text="This task is described in more details if you click on it."
android:textColor="#color/my_even_darker_gray" />
<TextView
android:id="#+id/tvAt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:paddingRight="5dp"
android:textColor="#color/my_even_darker_gray"
android:layout_toRightOf="#+id/tvUser"
android:background="#color/my_gray"
android:text="at" />
<TextView
android:id="#+id/tvDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/tvAt"
android:layout_alignBottom="#+id/tvAt"
android:layout_toRightOf="#+id/tvAt"
android:background="#color/my_gray"
android:text="12/02"
android:textColor="#color/my_even_darker_gray" />
<ImageView
android:id="#+id/iEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/tvComment"
android:layout_marginRight="4dp"
android:clickable="true"
android:contentDescription="#drawable/add_comment_button"
android:onClick="commentFragmentEditOnClick"
android:src="#drawable/add_comment_button" />
<ImageView
android:id="#+id/iRemove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/iEdit"
android:layout_toRightOf="#+id/iEdit"
android:layout_marginRight="4dp"
android:clickable="true"
android:contentDescription="#drawable/add_comment_button"
android:onClick="commentFragmentRemoveOnClick"
android:src="#drawable/add_comment_button" />
</RelativeLayout>
I would love for a little assistance.
Thanks.
I have a general advice for you that would solve your problem and help you in the future -
don't use android:onClick in the xml file, use setOnClickListener in the code itself - need to avoid mixing your views with other parts of the app as much as possible.
Try to keep the Fragment independent of its activity.
If the image is part of the fragment, why does the listener is part of the FragmentActivity?
Use setOnClickListener in the fragment itself, and you might be able to use this Framgent in other pats of the app without being depended on the Activity.
It would also solve your problem of identifying the fragment in which the image was clicked.
v is not an instance of Fragment, that's why Eclipse does not like your code. If you want the instance of a fragment you have to use the FragmentManager and one of its findFragmentByXXX methods.
To get the instance of the fragment that the ImageView was clicked in I did the following:
in the Fragment I set two onClickListeners for both of the images like this:
iEdit = (ImageView)rootView.findViewById(R.id.iEdit);
iEdit.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Log.d(TAG, "pressed edit button");
((PicturesAndCommentsActivity) getActivity()).commentFragmentEditOnClick(fragmentTag);
}
});
iRemove = (ImageView)rootView.findViewById(R.id.iRemove);
iRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
Log.d(TAG, "pressed remove button");
((PicturesAndCommentsActivity) getActivity()).commentFragmentRemoveOnClick(fragmentTag);
}
});
and in the fragment activity I defined those two methods like this:
public void commentFragmentRemoveOnClick (String tag)
{
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragmentManager.findFragmentByTag(tag)).commit();
}
for removing the fragment, and Now I'm working on editing the fragment.