How to access a TextView located in a Table Layout - android

I made a TableLayout 3x3 in "Activity A"(Chose a Table Layout, because I thought it suits my needs)
7 of the 9 cells are clickable and open "Activity B" which is a custom number picker I made.
I used an intent to pass an array and other data to activiy B
The idea of my number picker is to set a value in the cell I just clicked in Activiy A(I wanted something like the calendarDatePicker)
In "Activity B" I have a method to update the values from "Activity A" and finish() "Activity B" when an image View is clicked wich works very fine except that it does not set the value for the clicked Text View
How can I set the TextValue from another activity when the TextValue is contained in a Table Layout?
I don't use intent, because honestly I don't know how to handle it when the "Activity B" is closed.
I mean where in "Activity A" should I handle this intent from "Activity B"
Using the debugger I found out that trying to set the text using the TextView Id does not works as it shows a "null" object in the debugger.
Activiy A
package com.example.racu.threebythree;
public class threebythree extends AppCompatActivity {
public static ArrayList<Integer> ColumnA = new ArrayList<Integer>();
public static ArrayList<Integer> ColumnB = new ArrayList<Integer>();
public static ArrayList<Integer> ColumnC = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three_by_three);
for (int i = 1; i < 28; i++) {
if (i > 0 && i < 10)
ColumnA.add(i);
if (i > 10 && i < 19)
ColumnB.add(i);
if (i > 19 && i < 28)
ColumnC.add(i);
}
}
public void openNumberPicker(View v) {
// I used this to "guess" the location of the cell in the table layout as I could not find a way to do it.
String cellName = v.getResources().getResourceName(v.getId());
String cellLetter = cellName.substring(cellName.lastIndexOf("/") + 1);
// Send intent
Intent intent = new Intent(this, NumberPicker.class);
intent.putExtra("Id", (cellLetter.substring(0, 1) + cellLetter.substring(2)).toUpperCase());
switch (cellLetter.substring(0, 1)) {
case ("a"):
intent.putIntegerArrayListExtra("Column", ColumnA);
break;
case ("b"):
intent.putIntegerArrayListExtra("Column", ColumnB);
break;
case ("c"):
intent.putIntegerArrayListExtra("Column", ColumnC);
break;
}
intent.putExtra("Cell ID", v.getId());
startActivity(intent);
}
}
Avtivity B
package com.example.racu.threebythree;
public class NumberPicker extends AppCompatActivity {
GridView numberPicker;
ArrayList<Integer> numbersToDisplay;
TextView viewToDisplay;
ImageView ok, cancel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_number_picker);
numberPicker = (GridView) findViewById(R.id.arrayNumbers);
viewToDisplay = (TextView) findViewById(R.id.number_to_select);
ok = (ImageView) findViewById(R.id.add_number_to_card);
ok.setClickable(false);
Intent intent = getIntent();
String idFromIntent = intent.getStringExtra("Id");
numbersToDisplay = intent.getIntegerArrayListExtra("Letter");
TextView numberPosition = (TextView) findViewById(R.id.numberPosition);
numberPosition.setText(idFromIntent);
final TextView chosenNumber = (TextView) findViewById(R.id.chosenNumber);
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, R.layout.number_for_picker, numbersToDisplay);
numberPicker.setAdapter(adapter);
numberPicker.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
chosenNumber.setText(((TextView) v).getText());
ok.setImageResource(R.drawable.ok_blue);
ok.setClickable(true);
}
});
}
public void updateThreByThree(View v) {
Intent intent = getIntent();
int currentCell = intent.getIntExtra("Cell ID", 0);
String idFromIntent = intent.getStringExtra("Id").substring(0, 1);
TextView chosenNumber = (TextView) findViewById(R.id.chosenNumber);
// Here I try to Set the text to the cell in Activity A, using its R.id, but in the debugger I get a null reference, therefore my app crashes
TextView currentCellToEdit = (TextView) findViewById(currentCell);
currentCellToEdit.setText(chosenNumber.getText());
int temp = Integer.parseInt(chosenNumber.getText().toString());
switch (idFromIntent) {
case "A":
threebythree.ColumnA.remove(Integer.valueOf(temp));
break;
case "B":
threebythree.ColumnB.remove(Integer.valueOf(temp));
break;
case "C":
threebythree.ColumnC.remove(Integer.valueOf(temp));
break;
}
finish();
}
public void cancel(View view) {
finish();
}
}
Thanks to Pavan for the hint I found two more very helpful post here and this one was EXACTLY what I was looking for.

Like that ( make sure you give the TableLayout an id ):
TableLayout tl = (TableLayout)findViewById( R.id.tableLayout );
TextView tv = (TextView)tl.findViewById( R.id.textView );

Related

Android Studio onClick button to display ImageView in another activity (part 2)

I think i didn't describe properly what i meant in this question part 1 . So i enter more details here . Please have a look .
activityOne.java
EditText get_input;
Button get_button;
String display;
int image_id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
get_input=(EditText)findViewById(R.id.input_year);
get_button=(Button)findViewById(R.id.button_submit);
get_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int store_get_input=Integer.parseInt(get_input.getText().toString());
int results;
results=store_get_input%12;
if (results == 0) {
display = "Your number is "store_get_input";
image_id=0;
} else if (result ==1){
display = "Your number is "store_get_input";
image_id=1;
}else{
display = "Your number is others";
image_id=3;
}
Intent home_intent=new Intent(getApplicationContext(),Result_page.class);
home_intent.putExtra("home_store_get_input",display);
home_intent.putExtra("home_store_image_src",image_id);
startActivity(home_intent);
}
});
}
activityTwo.java
public class Result_page extends AppCompatActivity {
TextView get_result;
ImageView get_image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result_page);
get_result=(TextView)findViewById(R.id.display_result);
get_image=(ImageView)findViewById(R.id.image_view);
Intent result_intent=getIntent();
String text=result_intent.getStringExtra("home_store_get_input");
get_result.setText(text);// display what the user has enter
// get_image.setImageResource
//OR other coding to display imageview by using the image_id from activty 1?
}
From both java files, i think it will be clearer and easier for u guys to read. So i stuck at activityTwo.java the last past where I need to key in some codes in order to display the imageview by uising int image_id or other coding.
I don't think you need 2 duplicated questions.
Method 1: https://stackoverflow.com/a/38342798/2670771
Method 2:
In activity 1 just send image id to activity 2
if (results == 0) {
display = "Your number is "store_get_input";
image_id = R.drawable.image0;
} else if {...}
In activity 2 get image id from intent
int defaultIdWhenCouldNotFindImageSourceId = -1;//should use a negative value
int imageId = result_intent.getIntExtra("home_store_image_src", defaultIdWhenCouldNotFindImageSourceId);
if( defaultIdWhenCouldNotFindImageSourceId != imageId) {
//when you can find an valid image id in intent extra, display it
get_image.setImageResource(imageId);
}
Convert the string to integer in second activity and use a switch case for selecting image based on that number. Like :
Intent result_intent = getIntent();
String text = result_intent.getStringExtra("home_store_get_input");
try {
int number = Integer.parseInt(text);
} catch(NumberFormatException e) {
//Exception
}
int imageId = R.Drawable.default_image;
switch(number) {
case 1:
imageId = R.drawable.image1;
break;
case 2:
imageId = R.drawable.image2;
break;
........so on
}
ImageView.setImageResource(imageId);

Not able to start activity which is in another package (from intent)

I've got an activity where I can add bookmarks to a favourites list. Each favourite has got a button. When I click that button I have to go to that specific activity. But it shows me an error. The app doesn't crash, but the bookmarked activity isn't started from the click.
Here is the code for the "Favourites" activity:
public class FavouritesActivity extends Activity {
private TextView mEmptyText;
private LinearLayout mBookmarkLayout;
private Context mContext;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favourites_layout);
mContext = this;
mEmptyText = (TextView) findViewById(R.id.empty_textview);
mBookmarkLayout = (LinearLayout) findViewById(R.id.bookmark_insert_point);
getAllKeys();
}
private void getAllKeys()
{
SharedPreferences sp = this.getSharedPreferences("favs", MODE_PRIVATE);
Map<String,?> keys = sp.getAll();
int count = 0;
for(Map.Entry<String,?> entry : keys.entrySet())
{
String value = entry.getValue().toString();
System.out.println("!!!!!!!!!!!!!!!!!value = "+value);
String delimiter = ",";
String[] values_array = value.split(delimiter);
addBookmark(values_array);
count++; //keep track of the number of bookmarks
}
//if there are no bookmarks, display a text view saying so. Otherwise, make the text view go away
if (count == 0)
{
mEmptyText.setVisibility(View.VISIBLE);
mEmptyText.setText(getString(R.string.no_favs));
}
else
mEmptyText.setVisibility(View.GONE);
}
private void addBookmark(String[] values_array)
{
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.fav_individual, null);
TextView text = (TextView) v.findViewById(R.id.bookmark_text);
text.setSelected(true);
ImageButton button = (ImageButton) v.findViewById(R.id.bookmark_button);
v.getContext();
text.setText(values_array[1]);
final String myClass = values_array[0];
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Class<?> cl = null;
try {
cl = Class.forName(myClass);
Intent myIntent = new Intent(mContext, cl);
startActivity(myIntent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
});
// insert into main view
mBookmarkLayout.addView(v, 0, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
System.out.println("!!!!!!!!!!!!!!!!!!!!Just added a view");
}
}
The error is the onClick method, exactly in this line:
cl = Class.forName(myClass);
It gives me a ClassNotFoundException.
It seems that with this code I'm able to start an activity which is inside this package. But the problem is that the activity I want to start is inside a different package. The logcat says that it coulnd't find the activity in the current package.
So how can I open an activity from a different package in my case? Tha activity is declared in the manifest file.
Thank you.
Did you import the other package in your FavouritesActivity ?
Add this line at the top of your code and replace the words to match with your other package:
import com.yourotherpackage.name.yourclassname;

How to launch new view with the clicked argument?

I am new to android development - what I am not familiar with is how to send the user to a new view and include an argument (such as an item object) along with it. I would like to teach myself but I'm not quite sure what I am looking for. I think I need to send an intent to create a new view. In the overloaded "onItemClick" function you can see comments specifying exactly where I need to add code - this is the part I am not sure how to proceed on. Thanks for all help!
public class RoomActivity extends Activity {
GlobalClass globalClass;
TextView roomName;
TextView roomDescription;
Room thisRoom;
Button north;
Button south;
Button east;
Button west;
// this list view holds the options available in the room, each option is clickable and should
// bring up it's own subview
ListView listy;
// adaptor used to bind a string array of options to the list view
ArrayAdapter la;
/**
* Populates the main list view with the contents of list
* #param list an array of strings that are put into the list view
*/
public void populateList (int listID, ArrayList<String> list){
listy = (ListView) findViewById(listID);
la = new ArrayAdapter(this.getBaseContext(), R.layout.list_item, R.id.list_item_text, list.toArray());
listy.setAdapter(la);
listy.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3)
{
String value = (String)adapter.getItemAtPosition(position);
Item item = thisRoom.getItem(position);
// Verified that the item object is correctly populated.
// Send "item" as argument to the "activity_item" layout
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room);
globalClass = (GlobalClass) getApplicationContext();
if(thisRoom == null)
thisRoom = globalClass.getRoom(1);
roomName = (TextView) findViewById(R.id.room_name);
roomDescription = (TextView) findViewById(R.id.room_description);
north = (Button) findViewById(R.id.north_button);
south = (Button) findViewById(R.id.south_button);
east = (Button) findViewById(R.id.east_button);
west = (Button) findViewById(R.id.west_button);
setRoomView();
}
public void setRoomView () {
roomName.setText(thisRoom.getName());
roomDescription.setText(thisRoom.getDescription());
populateList(R.id.character_list, globalClass.getCharacterNames((thisRoom.getCharacters())));
populateList(R.id.item_list, globalClass.getItemNames(thisRoom.getItems()));
}
public void onClickMove (View view) {
Button button = (Button) view;
switch (button.getId()){
case (R.id.north_button):
if (thisRoom.northRoomId != 0){
thisRoom = globalClass.getRoom(thisRoom.northRoomId);
setRoomView();
}
break;
case (R.id.south_button):
if (thisRoom.southRoomId != 0){
thisRoom = globalClass.getRoom(thisRoom.southRoomId);
setRoomView();
}
break;
case (R.id.east_button):
if (thisRoom.eastRoomId != 0){
thisRoom = globalClass.getRoom(thisRoom.eastRoomId);
setRoomView();
}
break;
case (R.id.west_button):
if (thisRoom.westRoomId != 0){
thisRoom = globalClass.getRoom(thisRoom.westRoomId);
setRoomView();
}
break;
}
}
}
at your onItemClick()
Intent intent = new Intent(RoomActivity.this, ItemActivity.class);
String extra = "YOUR PASSED DATA";
intent.putExtra(EXTRA, extra);
startActivty();
at the RoomActivity class
public static final String EXTRA = "MY_EXTRA";
at ItemActivity.onCreate()
String item = getIntent().getStringExtra(RoomActivity.EXTRA);
I don't know if the Item class is Serializable or not, but in case it not: use Gson library to serialize/deserialize your Item object. It's easy to use; just read their guide.
At any case, I don't recommend this way of serializing and deserializing, you may extract the important fields (indeed primitives) from your Item at the RoomActivity and pass them using the Intent; and in the ItemActivity, just re-construct the Item.
Add this where you want to pass your data:
Intent intent = new Intent(this, DisplayMessageActivity.class);
intent.putExtra("MyData1", obj);
Add this where you want to retrieve you data:
getIntent().getSerializableExtra("MyData1");
Anyway, there's a good explanation on the official page on Android Developers here: http://developer.android.com/training/basics/firstapp/starting-activity.html
So here you go starting new Activity (view):
Intent i = new Intent(this, AnotherViewActivity.class);
i.putExtra("ExampleString", "Hello")
startActivity(i);
Getting sent data in the activity:
String data = getIntent().getExtras().getString("ExampleString");

Android application stops after setText on TextView

I have an android program which sends to another activity after clicking on a button. Mainly, I want to set the text from textview in the new windows so that it corresponds to the selected button. For example, if I click on button Writers, the next new activity should have a textview on which the word Writers appears. Everything works fine, except when I try to setText on the TextView icon for category. I also tried to call this change in the first activity, before launching the second one, it didn't work.
I also mention that if I comment the line with the setText, the program works just fine.
private String category;
public final static String CATEGORY_MESSAGE = "e.c.project.CATEGORY";
public void onClick(View v) {
switch(v.getId())
{
case R.id.actors:
category = "actors";
playTheGame(v);
break;
case R.id.cartoons:
category = "cartoons";
playTheGame(v);
break;
case R.id.singers:
category = "singers";
playTheGame(v);
break;
case R.id.writers:
category = "writers";
playTheGame(v);
break;
}
}
public void playTheGame( View view ){
Intent intent = new Intent(this, PlayGame.class);
String category = playGameButton.getText().toString();
intent.putExtra(CATEGORY_MESSAGE, category);
// TextView tv = (TextView) findViewById(R.id.categoryTV);
// tv.setText(category);
startActivity(intent);
}
this is the OnCreate method from the second activity:
private TextView categoryTV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String category = intent.getStringExtra(GameCategories.CATEGORY_MESSAGE);
categoryTV = (TextView) findViewById(R.id.categoryTV);
categoryTV.setText(category);
setContentView(R.layout.activity_play_game);
// Show the Up button in the action bar.
setupActionBar();
}
You need to call setContentView(R.layout.activity_play_game); before categoryTV = (TextView) findViewById(R.id.categoryTV); Otherwise your TextView is null
private TextView, categoryTV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_game); // make this call BEFORE initializing ANY views
Intent intent = getIntent();
String category = intent.getStringExtra(GameCategories.CATEGORY_MESSAGE);
categoryTV = (TextView) findViewById(R.id.categoryTV);
categoryTV.setText(category);
// Show the Up button in the action bar.
setupActionBar();
}
Your Views exist in your Layout so if you try to access any of them before inflating your Layout, with setContentView() or an inflater, they will be null resulting in a NPE when you try to call a method on them such as setText()

Refresh ListView with ArrayAdapter after editing an Item

I have a ListView, which displays a list of notes taken from a table in SQLiteDatabase with ArrayAdapter.
public class NotepadActivity extends ListActivity {
protected static final int ADD_NEW_NOTE = 0;
protected static final int EDIT_NOTE = 1;
ArrayAdapter<Note> adapter;
NotesManager manager;
private Note nNoteToDelete;
ArrayList<Note> lstAllNotes;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.btnAddNewNote).setOnClickListener(addNewNote);
manager = new NotesManager(this);
lstAllNotes = manager.getAllNotes();
adapter = new ArrayAdapter<Note>(this, R.layout.note, lstAllNotes);
setListAdapter(adapter);
getListView().setOnItemClickListener(editNote);
registerForContextMenu(getListView());
}
When I click on an Item in this ListView, it takes this Note object to the EditNote activity:
private OnItemClickListener editNote = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Note currNote = (Note)parent.getItemAtPosition(position);
int curr_note_id = currNote.getId();
String curr_note_title = currNote.getTitle().toString();
String curr_note_details = currNote.getDetails().toString();
Intent editNote = new Intent(NotepadActivity.this, EditNote.class);
editNote.putExtra("CURR_NOTE_ID", curr_note_id);
editNote.putExtra("CURR_NOTE_TITLE", curr_note_title);
editNote.putExtra("CURR_NOTE_DETAILS", curr_note_details);
startActivityForResult(editNote, EDIT_NOTE);
}
};
I can edit the title of the note in there and the content. When I hit the Save button, it sends back to the main activity the Strings of Title and the Details and the ID int:
public class EditNote extends Activity implements OnClickListener {
int curr_note_id;
String curr_note_title;
String curr_note_details;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editnote);
curr_note_id = getIntent().getExtras().getInt("CURR_NOTE_ID");
curr_note_title = getIntent().getExtras().getString("CURR_NOTE_TITLE");
curr_note_details = getIntent().getExtras().getString(
"CURR_NOTE_DETAILS");
((EditText) findViewById(R.id.edtTitle)).setText(curr_note_title);
((EditText) findViewById(R.id.edtDetails)).setText(curr_note_details);
findViewById(R.id.btnSave).setOnClickListener(this);
findViewById(R.id.btnCancel).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSave:
String strNoteTitle = ((EditText) findViewById(R.id.edtTitle)).getText().toString().trim();
String strNoteDetails = ((EditText) findViewById(R.id.edtDetails)).getText().toString().trim();
if (!strNoteTitle.equals("")) {
Intent data = new Intent();
data.putExtra("NOTE_ID", curr_note_id);
data.putExtra("NOTE_TITLE", strNoteTitle);
data.putExtra("NOTE_DETAILS", strNoteDetails);
setResult(RESULT_OK, data);
finish();
} else {
((EditText) findViewById(R.id.edtTitle))
.setError("A note must contain a title");
}
break;
case R.id.btnCancel:
setResult(RESULT_CANCELED);
finish();
break;
}
}
}
And in the main activity it should update the DB and the ListView with the new Title, if there were changes. My code does update the DB, but I don't see the change in the ListView immediately, only if I exit the app and open it again. Here's the code (watch the second case, EDIT_NOTE):
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case ADD_NEW_NOTE:
String noteTitle = data.getExtras().getString("NOTE_TITLE");
String noteDetails = data.getExtras().getString("NOTE_DETAILS");
Note nNewNote = new Note(-1, noteTitle, noteDetails);
adapter.add(nNewNote);
manager.addNote(nNewNote);
break;
case EDIT_NOTE:
int noteID = data.getExtras().getInt("NOTE_ID");
noteTitle = data.getExtras().getString("NOTE_TITLE");
noteDetails = data.getExtras().getString("NOTE_DETAILS");
nNewNote = new Note(noteID, noteTitle, noteDetails);
Toast.makeText(NotepadActivity.this, noteTitle + "\n" + noteDetails, Toast.LENGTH_SHORT).show();
manager.updateNote(nNewNote);
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
After manager.updateNote(nNewNote); I tried to use adapter.notifyDataSetChanged(); but that didn't work - I didn't see the change in the ListView. Perhaps I used it wrong, perhaps I should use something else...
So how can I make the ListView refresh? How can I see change immediately, without restarting the app?
Thank you!
When you return from the edit activity, set the list adapter again to refresh the ListView. You have to manually refresh the ListView each time if you want to see any updates. Hope this helps.

Categories

Resources