Storing in ArrayList based on Ascending Time - android

My current data structure is as follows:
public class MyDataTemplate {
long occurenceTime;
int val1;
int val2;
public MyDataTemplate(Long nanoTime, int val1, int val2) {
this.occurenceTime = nanoTime;
this.val1 = val1;
this.val2 = val2;
}
}
List<MyDataTemplate> myData = new ArrayList <MyDataTemplate>();
The occurenceTime(long) above represents the system time which I obtain in Android using System.nanoTime()
If data arrived sequentially by time, I could have very well used the above data structure to store data as and when it arrives:
newOccurence = new MyDataTemplate(System.nanoTime(), 42, 55)
myData.add(newOccurence);
However, since data does not arrive sequentially, I may get a new occurrence earlier than an old occurrence.
My task is to ensure that the myData contains data in ascending order of time, irrespective of when it arrives.
How can I ensure that ?

Froggy Oat...
I have made an attempt which seems to loosely illustrate a potential "solution:"
public class MainActivity extends AppCompatActivity {
public class MyDataTemplate {
long occurenceTime;
int val1;
int val2;
public MyDataTemplate(Long nanoTime, int val1, int val2) {
this.occurenceTime = nanoTime;
this.val1 = val1;
this.val2 = val2;
}
}
class SortByNanoTime implements Comparator<MyDataTemplate> {
public int compare(MyDataTemplate a, MyDataTemplate b) {
if (a.occurenceTime < b.occurenceTime)
return -1;
else if (a.occurenceTime > b.occurenceTime)
return +1;
else
return 0;
}
}
List<MyDataTemplate> myData = new ArrayList<MyDataTemplate>();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myData.add(new MyDataTemplate((long) 30000.2341, 2, 3));
myData.add(new MyDataTemplate((long) 234234.234, 3, 4));
myData.add(new MyDataTemplate((long) 11234234.234, 3, 4));
myData.add(new MyDataTemplate((long) 4.234, 3, 4));
Collections.sort(myData, new SortByNanoTime());
for (MyDataTemplate tempVar : myData) {
Log.i("XXX", "" + tempVar.occurenceTime);
}
}
}

You will want to use a priority queue or a tree set - - since your timestamps are nanos, the Comparator is simply a normal Integer compare.

Related

Save score after a Level, then use this to unlock things in the Menu. Unity 2D

Im currently working on a little mobile game in which you throw spears at targets, and depending on how many spears you have left at the end of the level you get between one and three Runes (similar to the Star scoring sytem in Angry Birds). The plan is to save the runes and use them to unlock different spear variants in the Main Menu.
At the moment you can see how many runes you got after completeing the level, but the values are not yet being saved.
My question is, how would I go about saving the Runes after each Level? Any ideas? You can see the part of the script Im using for that below. Thanks in advance.
public int totalRunes = 0;
public GameObject rune1;
public GameObject rune2;
public GameObject rune3;
public void RuneCollection()
{
if (currentSpears >= 2)
{
Debug.Log("3 runes collected!");
rune3.SetActive(true);
totalRunes = 3;
}
else if (currentSpears >= 1)
{
Debug.Log("2 runes collected!");
rune2.SetActive(true);
totalRunes = 2;
}
else
{
Debug.Log("1 rune collected!");
rune1.SetActive(true);
totalRunes = 1;
}
}
I would use Unitys PlayerPrefs System.
Example:
Setting Score:
public Text score;
int currentscore = 0;
Increasing Score:
currentscore += 1;
score.text = currentscore.ToString();
Setting HighScore and Loading Menu:
GameManager.SetHighScore(currentscore);
SceneManager.LoadScene("Menu");
Functions to Load/Change PlayerPrefs:
void Start()
{
highscore.text = PlayerPrefs.GetInt("HighScore", 0).ToString();
}
public static void SetHighScore(int score)
{
if (score > PlayerPrefs.GetInt("HighScore", 0))
{
PlayerPrefs.SetInt("HighScore", score);
}
}
Your Code adapted to PlayerPrefs:
public int currentSpears = 0;
public GameObject rune1;
public GameObject rune2;
public GameObject rune3;
void Start()
{
currentSpears = PlayerPrefs.GetInt("CurrentSpears", 0).ToString();
}
public static void IncreaseSpears()
{
int spears = PlayerPrefs.GetInt("CurrentSpears", 0);
PlayerPrefs.SetInt("CurrentSpears", spears++);
}
public void RuneCollection()
{
if (currentSpears >= 2)
{
Debug.Log("3 runes collected!");
rune3.SetActive(true);
totalRunes = 3;
}
else if (currentSpears >= 1)
{
Debug.Log("2 runes collected!");
rune2.SetActive(true);
totalRunes = 2;
}
else
{
Debug.Log("1 rune collected!");
rune1.SetActive(true);
totalRunes = 1;
}
}
You can save your data with PlayerPrefs for some single values or PersistentDataPath for some multiple values such as a class. Find out more with this link, and you can use them as below.
PlayerPrefs:
private int score = 0;
//set value
PlayerPrefs.SetInt("Score", score);
//get value
private int savedScore = PlayerPrefs.GetInt("Score");
PersistentDataPath:
private string savedName;
private int savedHealth;
private string loadedName;
private int loadedHealth;
public void Save(){
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/FileName.dat",
FileMode.Create);
PlayerClass newData = new PlayerClass();
newData.health = savedHealth;
newData.name = savedName;
bf.Serialize(file, newData);
file.Close();
}
public void Load(){
if (File.Exists(Application.persistentDataPath + "/FileName.dat")){
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/FileName.dat", FileMode.Open);
ObjData newData = (ObjData)bf.Deserialize(file);
file.Close();
loadedHealth = newData.health;
loadedName = newData.name;
}
}
[Serializable]
class PlayerClass{
public string name;
public int health;
}

Get int from textView

I'm trying to get the int value from a textView, the value inside will always be a number just in string, I set it like this
int randomNumber = rng.nextInt(6) + 1;
switch (randomNumber) {
case 1:
imageViewDice.setImageResource(R.drawable.dice1);
textView.setText("Tiraste un 1!");
if (player1.getText().equals("")) {
player1.setText("1");
} else {
player2.setText("1");
}
break;
//rest of cases 2, 3, 4, 5, & 6
I need the int value of this to be able to compare then to see which player (1 or 2) has the highest number, something like this
//this doesnt work
int value1 = Integer.parseInt(player1.getText().toString());
int value2 = Integer.parseInt(player2.getText().toString());
if (value1 > value2) {
result.setText("Jugador 1");
} else if (value1 < value2) {
result.setText("Jugador 2");
} else {
result.setText("Empate!");
}
What is the correct way to get the value so that the comparison can be made?
if you set static, you can very easily read in various classes:
player1.setText(Fraction.getP1()+"");
player2.setText(Fraction.getP2()+"");
if(Fraction.getP1()>Fraction.getP2())
result.setText("Jugador 1");
new class
public class Fraction {
private static int p1=0;
private static int p2=0;
public static int getP1(){
return p1;
}
public static int getP2(){
return p2;
}
public static void setP1(int p1fraction){
Fraction.p1 = p1fraction; //Fraction is your class name
}
public static void setP2(int p2fraction){
p2 = p2fraction;
}
}

Load More RecyclerView Error Cannot Call this method

I need help for this load more RecycleView, I create 'Recyclerview', first, limit 5 data and showing, but when I scroll until the end no 'ProgressBar' showing and the next data now showing, I check the 'logcat' no error only warning
this my load more function
private void loadMore() {
arraylist.add(null);
mListadapter.notifyItemInserted(arraylist.size() - 1);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
arraylist.remove(arraylist.size() - 1);
int scrollPosition = arraylist.size();
mListadapter.notifyItemRemoved(scrollPosition);
int currentSize = scrollPosition;
int nextLimit = currentSize + 5;
Log.e("currentSize",""+currentSize);
Log.e("nextLimit",""+nextLimit);
if(nextLimit <= DataNoteImformation.id.length) {
while (currentSize + 1 <= nextLimit) {
DataNote wp2 = new DataNote(
DataNoteImformation.id[currentSize],
DataNoteImformation.branchArray[currentSize],
DataNoteImformation.assetcodeArray[currentSize],
DataNoteImformation.customerArray[currentSize],
DataNoteImformation.licenseplateArray[currentSize]
);
arraylist.add(wp2);
currentSize++;
}
}else {
while (currentSize + 1 <= DataNoteImformation.id.length) {
DataNote wp2 = new DataNote(
DataNoteImformation.id[currentSize],
DataNoteImformation.branchArray[currentSize],
DataNoteImformation.assetcodeArray[currentSize],
DataNoteImformation.customerArray[currentSize],
DataNoteImformation.licenseplateArray[currentSize]
);
arraylist.add(wp2);
currentSize++;
}
}
mListadapter.notifyDataSetChanged();
isLoading = false;
}
}, 2000);
}
and the warning in logcat
W/RecyclerView: Cannot call this method in a scroll callback. Scroll callbacks might be run during a measure & layout pass where you cannot change theRecyclerView data. Any method call that might change the structure of the RecyclerView or the adapter contents should be postponed to the next frame.
and this example data
public class DataNoteImformation {
public static String[] branchArray = {"Depok","Jakarta","Bekasi","Jakarta","Jakarta","Bekasi","Bogor","Jakarta","Bekasi","Jakarta"};
public static String[] assetcodeArray = {"0092","0084","0091","0084","0084","0078","0089","0073","0027","0021"};
public static String[] customerArray = {"Kevin Sanjaya","Indah Permata","Riyan","Puri Setiawan","Herman","Iwan","Ratna","Agus","Danang","Ujang"};
public static String[] licenseplateArray = {"B 9829 SK","B 8294 LK","B 9090 NBA","B 7627 SKA","B 7637 SAK","B 6763 KIK","F 7287 NB","F8792KI","B8273KD","B7728KSI"};
public static String[] id = {"1","2","3","4","5","6","7","8","9","10"};
}
how to fix this.

Android Beginner // Why are my Variables all 0 after i should have filled them?

I just edited this post from my original one, because i could narrow the Problem down, but didn´t want to open an extra post for it.
What i Want
I have an Activity in which i generate Data from Houses into an Array. Then on opening another Activity the Data should be used for displaying it.
My Problem
The Data gets generated correctly, and I can see in my Logs that it is generated before i want to access it. At access it still doesn´t show me my Data.
My Code
Houses.java (Where i generate the Houses and use the Answer already given below to try to get my Data)
public class Houses{
int[][] NewHouseProps = new int[20][10];
int[][] HouseProps;
public Houses(){
}
public ArrayList<Integer> getClasses()
{
ArrayList<Integer> classes = new ArrayList<>();
Log.d("Test","ID: "+3+" CLASS: "+NewHouseProps[3][0]);
Log.d("Test","ID: "+4+" CLASS: "+NewHouseProps[4][0]);
for(int id=0 ; id<=8; id++) {
classes.add(NewHouseProps[id][0]);
Log.d("getClasses","Classes: "+NewHouseProps[id][0]);
Log.d("getClasses!!!!!!!!!", "List: "+classes.get(id));
}
return classes;
}
public void GenerateHouses(){
Log.d("Generate Houses","!!");
for(int id=0; id<=8; id++){
Random r = new Random();
int h_class, garage = 0, rooms = 0, furn = 0, balkon = 0, pool = 0;
h_class = r.nextInt(4); //Klasse
if(h_class == 0){
rooms = r.nextInt(4)+1;
balkon = r.nextInt(1);
}else if(h_class == 1){
rooms = r.nextInt(3)+3;
garage = r.nextInt(1)+1;
pool = r.nextInt(1);
balkon = r.nextInt(2);
}else if(h_class == 2){
rooms = r.nextInt(3)+2;
garage = r.nextInt(2)+2;
pool = r.nextInt(1);
}else if(h_class == 3){
rooms = r.nextInt(8)+6;
garage = r.nextInt(6)+4;
pool = r.nextInt(1);
balkon = r.nextInt(3);
}
furn = r.nextInt(1);
int price = GenerateHousePrice(id, h_class, garage, rooms, furn, balkon, pool);
NewHouseProps[id][0] = h_class;
NewHouseProps[id][1] = price;
NewHouseProps[id][2] = rooms;
NewHouseProps[id][3] = furn;
NewHouseProps[id][4] = balkon;
NewHouseProps[id][5] = pool;
NewHouseProps[id][6] = garage;
Log.d("ID: ", Integer.toString(id));
Log.d("CLASS: ",Integer.toString(NewHouseProps[id][0]));
Log.d("PRICE: ", Integer.toString(NewHouseProps[id][1]));
}
}
public int GenerateHousePrice(int id, int h_class, int garage, int rooms, int furn, int balkon, int pool){
int price = 0, pricep = 0;
Random r = new Random();
if(h_class == 0){
price = r.nextInt(150000)+50000; // 50 - 200 tausend
price += rooms * 7500;
}
else if(h_class == 1){
price = r.nextInt(165000)+85000; //85 - 250 tausend
price += rooms * 12500;
}
else if(h_class == 2){
price = r.nextInt(300000)+100000; //100 - 400 tausnd
price += rooms * 20000;
}
else if(h_class == 3){
price = r.nextInt(800000)+500000; // 500 - 1.3 Mill.
price += rooms * 15000;
}
if(garage > 0){
pricep += price*0.20;
pricep += garage * 500;
}
if(furn == 1){
pricep += price*0.25;
}
if(balkon > 0){
pricep += price*0.1;
pricep += balkon*500;
}
if(pool == 1){
pricep += 20000;
}
price += pricep;
return price;
}
BuyHousesActivity.java(Here the Data should be accessed and displayed)
public class BuyHousesActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buy_houses);
Houses h = new Houses();
ArrayList<Integer> classes = h.getClasses();
for(int id=0;id<=8;id++){
Log.d("OnCreate Classes: ","Classes: "+classes.get(id));
}
List<Integer> images = new ArrayList<>();
images.add(R.drawable.apartment);
images.add(R.drawable.townhouse);
images.add(R.drawable.bungalow);
images.add(R.drawable.villa);
ViewPager viewPager = findViewById(R.id.vpPager);
viewPager.setAdapter(new MyViewPagerAdapter(getSupportFragmentManager(), images));
}
protected class MyViewPagerAdapter extends FragmentStatePagerAdapter {
private List<Integer> imageList;
MyViewPagerAdapter(FragmentManager fm, List<Integer> images) {
super(fm);
imageList = images;
}
#Override
public int getCount() {
return imageList.size();
}
#Override
public Fragment getItem(int position) {
return FragmentBuyHouse.newInstance(imageList.get(position));
}
}
My Logs
Those are the Results of my Logs, with them in place like u see above:
Generating
Accessing
I hope you can help me and show me what i got wrong and/or forgot.
This is happening because you are using a empty list. Look.
In your FragmentBuyHouse you call:
BuyHousesActivity bha = new BuyHousesActivity();
List<Integer> classes = bha.classes;
But when you instance new BuyHouseActivity(), it initialize the array, with none data.
Look your class BuyHouseActivity
List<Integer> classes = new ArrayList<>();
In your implemantation, you populate it array classes in method onCreate() that's not called when you instace the class. This is the reason because you have the error on line 46.
You need pass the data by parameter like you make using Bundle.
Solution 2
You can create a static method to return classes:
Change your BuyHousesActivity:
public class BuyHousesActivity extends FragmentActivity {
List<Integer> classes = new ArrayList<>();
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Houses h = new Houses(); //Activity where my Houses get generated
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buy_houses);
Log.d("1. Step", "!!!!!!!!!!!!!!!!!!!!!!");
// for(int id=0; id<=8;id++){
// classes.add(h.NewHouseProps[id][0]);
// Log.d("Klasse: ", Integer.toString(h.NewHouseProps[id][0]));
// }
// Log.d("2. Step", "!!!!!!!!!!!!!!!!!!!!!!");
/*
classes.add(R.drawable.apartment); //Class 0
classes.add(R.drawable.townhouse); //Class 1
classes.add(R.drawable.bungalow); //Class 2
classes.add(R.drawable.villa); //Class 3
*/
mPager = findViewById(R.id.vpPager);
mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), classes);
mPager.setAdapter(mPagerAdapter);
}
public static ArrayList<Integer> getClasses()
{
Houses h = new Houses();
classes = new ArrayList<>();
for(int id=0 ; id<=8; id++) {
classes.add(h.NewHouseProps[id][0]);
}
return classes;
}
#Override
public void onBackPressed() {
//ViewPager Last Page or Back
if (mPager.getCurrentItem() == 0) {
super.onBackPressed();
} else {
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
And you want get classes like your FragmentBuyHouse
public class FragmentBuyHouse extends Fragment {
private int[] imageResId;
private int fragnumber;
BuyHousesActivity bha = new BuyHousesActivity();
List<Integer> classes = bha.getClasses();
...
}

Read value from list view row

I display in a list view some team members. The plan is to get the teamId with the maximum number of steps. The below method demonstrates how I am achieving that.
public void readLeagueMembers(JSONObject response){
JSONArray teamsArray = null;
try {
teamsArray = response.getJSONArray("teams");
for (int i = 0; i < teamsArray.length(); i++) {
leagueMembers = new LeagueMembers();
JSONObject team = teamsArray.getJSONObject(i);
leagueMembers.setTeamId(team.getString("ID"));
leagueMembers.setTeams(team.getString("team_name"));
leagueMembers.setLeaguePoints(team.getString("team_points"));
leagueMembersList.add(leagueMembers);
listView.setAdapter(leagueAdapter);
//String[] team_points = new String[]{leagueMembers.getLeaguePoints()};
teamId = leagueMembersList.get(0).getTeamId();
Log.d("teamId",teamId);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
You see from that method the variable teamId(which is static) where it stores the first row's teamId which is 645.
Now I am passing this value to another class which is a CountDownTimer one.
public class CounterClass1 extends CountDownTimer {
public CounterClass1(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
long seconds = millisUntilFinished / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
String time = days+"d"+ ":" + hours % 24+"h" + ":" + minutes % 60 +"m"+ ":" + seconds % 60+"s";
diffDays.setText("League finishes in: " + time);
}
#Override
public void onFinish() {
diffDays.setText("League Finished");
viewResults.setVisibility(View.VISIBLE);
leagueInvitation.setVisibility(View.GONE);
winnerId = League.teamId;
Log.d("team id",winnerId);
viewResults(leagueId, winnerId, results, username, password);
}
}
As shown I read the static variable teamId from another class
winnerId = League.teamId;
and store it to a variable called winnerId. Unfortunately winnerId is read as null from the debugger. Any suggestions? Surely it is a Java problem not an Android one.
Thanks.
First of all where is your leagueadapter. Whare you initialize it . And second thing you are setting adapter inside loop that is wrong. It will set adpter again and again if you have more that one oblect inside json array .
And for the team id you can create a singleton class and set team id there in a instance varible .and get that id whereever you want .Here is tha code fro singleton class you need .
public class ReferenceWrapper {
private static ReferenceWrapper wrapper;
private int teamId;
private Context context;
private ReferenceWrapper(Context context) {
this.context=context;
}
public static ReferenceWrapper getInstance(Context context) {
if (wrapper == null) {
wrapper = new ReferenceWrapper(context);
}
return wrapper;
}
public int getTeamId(int teamId) {
return teamId;
}
public int setTeamId() {
this.teamId=teamId;
}
}

Categories

Resources