Why I can't seem to update my gridview from oncreate? - java

I have the following OnCreateMethod()
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_siege_main);
mContext = getApplicationContext();
gridview = (GridView) findViewById(R.id.gridview_board);
initialBoard = new Board();
initialBoard.generate(Globals.rand_width,
Globals.rand_height,
Globals.rand_low,
Globals.rand_high);
gridview.setAdapter(new BoardAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//updateGameState(initialBoard);
}
});
updateGameState(initialBoard);
//typography
TextView boardName = (TextView) findViewById(R.id.textview_board_name);
boardName.setText("Uncharted Territory");
Toast.makeText(SiegeMainActivity.this, "Uncharted Territory loaded", Toast.LENGTH_SHORT).show();
Typeface face = Typeface.createFromAsset(getAssets(),
"fonts/calibri-1.ttf");
boardName.setTypeface(face);
TextView pl1Name = (TextView) findViewById(R.id.textViewPlayer1Name);
face = Typeface.createFromAsset(getAssets(),
"fonts/calibri-1.ttf");
pl1Name.setTypeface(face);
TextView pl2Name = (TextView) findViewById(R.id.textViewPlayer2Name);
face = Typeface.createFromAsset(getAssets(),
"fonts/calibri-1.ttf");
pl2Name.setTypeface(face);
}
and my updateGameState() method is like this:
private void updateGameState(Board b) {
int [] vals = b.getLinearVals();
int [] plays = b.getLinearPlays();
int [] score = b.getScore();
int turns = b.getTurns();
Button tile;
//updating board
for(int i=0;i<gridview.getChildCount();i++){
tile = (Button)gridview.getChildAt(i);
tile.setText(""+vals[i]);
if(plays[i]==1)
tile.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.btn_default_normal_green));
else if (plays[i]==2)
tile.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.btn_default_normal_blue));
}
//Setting the score
Button pl1Score, pl2Score;
pl1Score = (Button) findViewById(R.id.buttonPlayer1Score);
pl2Score = (Button) findViewById(R.id.buttonPlayer2Score);
pl1Score.setText(""+score[0]);
pl2Score.setText(""+score[1]);
}
When I call updateGameState() in OnCreate after creating the adapter, it should fill the buttons with some values. But it doesn't seem to work. But when I do the same thing on a click (commented out in the click listener), it seems to work fine. I want to populate the values on loading the page. Can somebody help me?

You need to let the GridView know that the data has changed. If you are dynamically changing the data in the ArrayAdapter, you need to call BoardAdapter.notifyDataSetChanged() so the GridView can "refresh" itself with the new data.
In your case, you need to create a reference to you new BoardAdapter and then use that to call the notifyDataSetChange() method.
private BoardAdapter boardAdapter = null;
protected void onCreate(Bundle savedInstanceState) {
// your things
boardAdapter = new BoardAdapter(this);
gridview.setAdapter(boardAdapter);
// more things
}
private void updateGameState(Board b) {
// update your data
boardAdapter.notifyDataSetChanged();
}
Edit: You mentioned in the comment that you tried using an ArrayAdapter and it didn't work for you... maybe try this, which says to use the GridViews invalidateViews() method. gridView.invalidateViews()

Have a look at this SO question & answer here:
How to refresh a GridView?
I had a similar problem, but couldn't get it to even refresh on a button click, even tho items were being changed and added. In my case, the trick, as it turns out, was to recreate the (in your case) BoardAdapter with the new/updated list of items, and then reassign it to the gridview.
gridViewAdapter = new MyGridViewAdapter(this, blah, yourUpdatedItems);
discoverGridView.InvalidateViews();
discoverGridView.Adapter = gridViewAdapter;
I am sure there has to be a better, more reactive, way of doing it, but this at least got my proof of concept up and running.

Related

Generate any number of Views

I want to generate multiple TextViews based on how many semicolons the users enters between inputs in an EditText.
And it works so far, the only problem is that all TextViews are on top of each other, so I need to have the second TextView be positioned below the first and so on.
I tried to use setY but it did not change the position of the Views or they disappeared completely.
Is there a method to achieve this or is this a case for the LayoutInflater?
public class MainActivity extends AppCompatActivity {
private EditText et1;
private ScrollView sv1;
private ConstraintLayout cl1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et1 = findViewById(R.id.editText);
sv1 = findViewById(R.id.scrollView);
cl1 = new ConstraintLayout(this);
sv1.addView(cl1);
}
public void splitToChips(View v) {
String content = et1.getText().toString();
String[] products = content.split(";");
TextView[] textViews = new TextView[products.length];
for(int i = 0; i<products.length; i++) {
textViews[i] = new TextView(this);
cl1.addView(textViews[i]);
textViews[i].setText(products[i]);
}
}
}
You should add views to LinearLayout. In my case, I created a layout with a Button, EditText, and LinearLayout along with a vertical orientation inside of a ScrollView. Then, in the Java code, I simply added the following line to the loop:
mLinearLayout.addView(textViews[i]);

How can I open A Custom ListView Item in A separate Activity?

I have looked through other Posts as much as I can, and though this may be a simple problem, for the life of me I can't figure out how to make this work. I have a Database of Customers, including their names, address, etc.
I would Like to be able to select one of the customers from my custom ListView, and View all of their Database information in A separate Activity. Currently, I cant make it give me anything past the first record.
Any advice would be very helpful if you can see what I am doing wrong.
I am fairly new to Java so Please take it easy on me :P My best guess right now is that I need to create a new cursor but I'm a bit lost.
Code attached below.
Database Viewer.java
public class DatabaseViewer extends AppCompatActivity{
TextView DisplayName;
TextView DisplayID;
TextView DisplayMarks;
TextView DisplayAddress;
DatabaseHelper mydb = new DatabaseHelper(this);
ListView customerlist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_database_viewer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
customerlist = (ListView) findViewById(R.id.ListViewCustomers);
populateDatabase();
customerlist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
DisplayID = (TextView) findViewById(R.id.TVCUSTOMERNAME);
DisplayMarks = (TextView) findViewById(R.id.TVADDRESS);
DisplayName = (TextView) findViewById(R.id.TVID);
DisplayAddress = (TextView) findViewById(R.id.TVMARKS);
// NEED TO MAKE A CURSOR THAT GETS ALL ROWS NOT COLUMNS LIKE BELOW.
int c1 = mydb.getallrows().getPosition();
// 35 ROWS 4 COLUMNS.
String item = String.valueOf(parent.getItemAtPosition(i));
Intent clientViewIntent = new Intent(DatabaseViewer.this, ClientViewer.class);
clientViewIntent.putExtra("Client ID", c1);
startActivity(clientViewIntent);
}
});
}
private void populateDatabase(){
Cursor c = mydb.getallrows();
customerlist = (ListView) findViewById(R.id.ListViewCustomers);
String[] fromfieldnames = new String[] {DatabaseHelper.COL_1, DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4};
int[] tofieldnames = new int[] {R.id.TVCUSTOMERNAME, R.id.TVADDRESS, R.id.TVMARKS, R.id.TVID};
SimpleCursorAdapter adapter;
adapter = new SimpleCursorAdapter(getBaseContext(), R.layout.custom_db_viewer_row, c, fromfieldnames, tofieldnames, 0);
customerlist.setAdapter(adapter);
}
public void OnClientLongPress(){
// Function to Open up Client Information in a new activity.
// Step 1, Use data from Client to pull up Full Client Records.
// Step 2, Send Data in Intent Extras.
Intent clientVIewIntent = new Intent(DatabaseViewer.this, ClientViewer.class);
clientVIewIntent.putExtra("Client ID", customerlist.getSelectedItemId());
startActivity(clientVIewIntent);
}
ClientViewer.java
public class ClientViewer extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client_viewer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.inflateMenu(R.menu.menu_invoice_creator);
Bundle NameIntentData = getIntent().getExtras();
if (NameIntentData==null){
return;
}
int IntentDataID = NameIntentData.getInt("Client ID");
String IntentDataName = NameIntentData.getString("Client Name");
String IntentDataAddress = NameIntentData.getString("Client Address");
final TextView IDBar = (TextView) findViewById(R.id.ClientViewerIDTV);
final TextView Namebar = (TextView) findViewById(R.id.ClientViewerNameTV);
final TextView AddressBar = (TextView) findViewById(R.id.ClientViewerAddressTV);
Namebar.setText(Integer.toString(IntentDataID));
IDBar.setText(IntentDataName);
AddressBar.setText(IntentDataAddress);
}
}
Thanks so much for your time and effort guys. Really cant wait to hear back from you.
TextView textview =((TextView)view.findViewById(R.id.tvInVisitorName)).getText().toString();
Use this on onClick and get your text view data like this.
Get the ID of client onClick which is same and unique as stored in DB
Then, pass it to another activity
Pass id parameter and get all the data based on that ID and display..don't pass all the data via intent just pass one key and get all data and display
Hope this will help you
Thanks!!!
SOLVED, Largely in thanks to Anamica!
The code
String a = Long.toString(l);
Intent clientViewIntent = new Intent(DatabaseViewer.this,
ClientViewer.class);
clientViewIntent.putExtra("Client ID", a);
startActivity(clientViewIntent);
Got me where I needed to be.(Shows the Id of Item) Thanks again Guys!

show something when listview is empty

I have a listview that shows up when a fragment is opened being updated by a saved list. Initially that list is empty so it spits out an error java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0. So i want to show show something like a text saying something like empty so that when there is something in the list it will display. I have tried using the getEmptyView but to no avail. Can i please get some help on how to accomplish this thank you.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View customView = inflater.inflate(R.layout.fragment_reading_monday, container, false);
addNewButton = (Button) customView.findViewById(R.id.btnAddNewReadingMonday);
relativeLayoutMonday = (RelativeLayout) customView.findViewById(R.id.frameLayoutMonday);
listViewMonday = (ListView)customView.findViewById(R.id.listViewMonday);
listContainerMonday = (RelativeLayout)customView.findViewById(R.id.listContainerMonday);
tinyDB = new TinyDB(getContext());
addNewSubject = (Button)customView.findViewById(R.id.btnAddNewSubjectMonday);
dataModels = new ArrayList<>();
arrayListSubjectsRead = new ArrayList<>();
timeOne = new ArrayList<>();
timeTwo = new ArrayList<>();
adapter = new CustomListAdapterReading(getContext(), dataModels);
TextView empty = (TextView) customView.findViewById(R.id.emptyTextView);
listViewMonday.setEmptyView(empty);
arrayListSubjectsRead = tinyDB.getListString("ArrayForSubjects");
timeOne = tinyDB.getListString("ArrayForTimeOne");
timeTwo = tinyDB.getListString("ArrayForTimeTwo");
dataModels.add(new DataModelReading(arrayListSubjectsRead, timeOne, timeTwo));
adapter = new CustomListAdapterReading(getContext(), dataModels);
listViewMonday.setAdapter(adapter);
adapter.notifyDataSetChanged();
System.out.println(" subjects: "+arrayListSubjectsRead);
System.out.println("timeone: "+ timeOne);
System.out.println("timetwo: "+timeTwo);
addNewButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
relativeLayoutMonday.removeView(noEventTextView);
Intent intent = new Intent(getActivity(),ReadMain.class);
startActivity(intent);
}
});
addNewSubject.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return customView;
}
I want you to check this post setEmptyView on ListView not showing its view in a android app, it should solve your empty view issue.
And if you want to prevent the app from throwing an IndexOutOfBoundsException, you can simply check the size of your dataModels array before setting up your adapter.
if (dataModels.size() > 0)
{
//Setup our adapter here
}
Hope this helps :)
Something like this ?
ImageListAdapter imageListAdapter= new ImageListAdapter();
listviewObject.setAdapter(imageListAdapter);
if (imageListAdapter!= null)
if (imageListAdapter.getCount() > 0){
// implement your work
}else {
// do whatever you want on empty list adapter
}
I am using this way in my application
ListView listView = (ListView)findViewById(android.R.id.listView);
TextView noData = (TextView)findViewById(android.R.id.noData);
listView.setEmptyView(noData);
Listview will automatically set no data text when adapter is empty.

how to set a text views text to an integer value of an object that was created from another class

the title is a bit confusing sorry about that i didnt know how to put it in words properly. I have a listView that uses an Adapter that i created myself. When the first row of the listView is pressed I have made it so it creates a new object from class called Ship that has 3 integer values. Below
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hangar);
ListAdapter adapter = new HangarAdapter(this, ship);
hangarList.setAdapter(adapter);
hangarList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Intent sendListEvents = new Intent();
if(position == 0)
{
Ship ship1 = new Ship();
ship1.setAddAmount(50);
ship1.setAddTime(5000);
ship1.setAddSpend(1000);
ship1.shipAdd();
}
}
}
In my adapter i have a textView called TextView2 and I want to set the text of it to ship1's value called addSpend. How do i do that.
if (position == 0) {
theImageView.setImageResource(R.drawable.planet);
TextView2.setText("This is where I want ship1's addSpend value to be displayed")
}
Well if I am correct then you have in the HangarAdapter class the object this (which references to the Activity in which you are right now: ListAdapter adapter = new HangarAdapter(this, ship);). Save this object to an variable (I call it MainActivity) in the HangarAdapter class .
Now you could just say in the HangarAdapter class: MainActivity.findViewById("TextBoxID").setText("MUHAHAHAH")

Creating a spinner dynamically

I was struggling to create a spinner dynamically. I had it on the page but every time I tried to select an option it would blow up. My original code is at the bottom. I fixed it by moving the addSpinner() function outside of the inner class and changing
Spinner newSpinner = new Spinner(getApplicationContext());
to
Spinner newSpinner = new Spinner(this);
It's fixed but I have no idea what it didn't work initially. Can anyone explain? (apologies if it's a noob question - I am new to both Java and android)
public class SpotManageActivity extends Activity
{
private SimpleCursorAdapter mSpots;
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.reminder_manage_activity);
Button add_new_button = (Button) findViewById(R.id.add_new_spot_button);
add_new_button.setOnClickListener(new ButtonOnClickListener());
}
public class ButtonOnClickListener implements View.OnClickListener
{
#Override
public void onClick(View v)
{
addSpinner();
}
private void addSpinner()
{
LinearLayout layoutHolder =
(LinearLayout) findViewById(R.id.layout_holder);
LinearLayout spinnerHolder = new LinearLayout(getApplicationContext());
spinnerHolder.setOrientation(LinearLayout.HORIZONTAL);
spinnerHolder.setLayoutParams(
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1f));
Spinner newSpinner = new Spinner(getApplicationContext());
newSpinner.setLayoutParams(
new Spinner.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
newSpinner.setAdapter(mSpots);
layoutHolder.addView(spinnerHolder);
spinnerHolder.addView(newSpinner);
// A non-internal spot was selected
}
}
}
I am not sure at all, but if in the stack trace you're getting something about a wrong context, it's probably because a Spinner, when clicked, opens a Dialog, and a Dialog needs an Activity context.
For more info:
Android - what's the difference between the various methods to get a Context?
Dialog throwing "Unable to add window — token null is not for an application” with getApplication() as context

Categories