Adding an array of views crashes an android app - java

I have some part of an android app here which crashes for no apparent reason.
RL0 happens to be some LinearLayout defined in XML which already contains some other irrelevant stuff. To be honest with you, I've mostly worked with C++ so I might not initially know much about why some things are done significantly different in android, but I'm putting effort. Any help on how I can fix that crash?
Error message states NullPointerException.
Thanks.
public class Osteoporoza extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_osteoporoza);
LinearLayout RL0=(LinearLayout)findViewById(R.id.RL0);
page[] pages=new page[10];
RL0.addView(pages[0].pageLL0);//doesn't crash without this line, yet i need to have some way of adding n objects that follow a pattern, i.e. a class.
class page
{
public LinearLayout pageLL0;
public ScrollView pageUpperScroll1;
public TextView pageTextView2;
public ScrollView pageLowerScroll1;
public LinearLayout pageAnswerButtonLL2;
public Button AnswerButton3_1;
public Button AnswerButton3_2;
public Button AnswerButton3_3;
public Button AnswerButton3_4;
page()
{
pageAnswerButtonLL2.addView(AnswerButton3_1);
pageAnswerButtonLL2.addView(AnswerButton3_2);
pageAnswerButtonLL2.addView(AnswerButton3_3);
pageAnswerButtonLL2.addView(AnswerButton3_4);
pageLowerScroll1.addView(pageAnswerButtonLL2);
pageUpperScroll1.addView(pageTextView2);
pageLL0.addView(pageUpperScroll1);
pageLL0.addView(pageLowerScroll1);
}
}

All elements in an Object array are null by default.
I.e. when you create the array:
page[] pages = new page[10];
you are only setting the size of the array but not setting any instances within the array itself so every element will be null. To instantiate each element you need to use:
for (int i=0; i < pages.length; i++) {
pages[i] = new page();
}
Note Java naming conventions show that class names start with an uppercase letter, for example
Page[] pages = new Page[10];

- You have declared the Array but didn't initialize it.
Eg:
page[] pages = new page[10]; // Tell that this is an Array of page of length 10
- You will need to Initialize it,
Eg:
for (page p : pages){
p = new page();
}
- Please use the Collection like ArrayList instead of Array, as its far more flexible than using an Array.
- ArrayList can hold null values, and unlike Array, its size can increased.
ArrayList<page> p = new ArrayList<page>();
- Always make the 1st letter of a class, enum , interface as Capital.
Eg:
It should Not page but Page

Related

"Cannot resolve method" unable to access object methods inside a loop (passing object reference to function)

I'm new to Android and JAVA,... my Activity have many widgets that are inside separated LinearLayouts. I want to toggle them on and off accordingly. I have some radio buttons which will hide or show certain LinearLayouts as required. It makes more sense to me having the widgets grouped as sections for this case.
I'm having a problem accessing the methods "getVisibility" and "setVisibility" from inside a "for" loop. I'm using an array of Object type. I thought in maybe just pass the layouts id's as strings but something tells me it will not work.
As a side question : I have 13 total Linear Layouts in a single activity is it bad practice? I could not find a better way to horizontal align elements, maybe I took the short route? :p Thanks in advance.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_job);
...
LinearLayout monthlyContainer = (LinearLayout) findViewById(R.id.monthlyContainer);
LinearLayout weeklyContainer = (LinearLayout) findViewById(R.id.weeklyContainer);
LinearLayout fortnightlyContainer = (LinearLayout) findViewById(R.id.fortnightlyContainer);
LinearLayout fourweeklyContainer = (LinearLayout) findViewById(R.id.fourweeklyContainer);
LinearLayout twiceMonthlyContainer = (LinearLayout) findViewById(R.id.twiceMonthlyContainer);
RadioGroup earningsContainer = (RadioGroup) findViewById(R.id.earningsContainer);
///create a list of views to hide
Object[] viewsToToggle={monthlyContainer, weeklyContainer, fortnightlyContainer, fourweeklyContainer, twiceMonthlyContainer, earningsContainer};
//pass object array to hideView method
this.hideView(viewsToToggle, monthlyContainer);
....
}
private void hideView(Object[] viewsToToggle, Object excludeMe){
///// create array to contain elements to toggle visibility
Object[] viewstoHide = new Object[4];
for(int i = 0; i < viewsToToggle.length; i++){
if(viewsToToggle[i] != excludeMe){
viewstoHide[i] = viewsToToggle[i];
}
}
for(int j = 0; j < viewstoHide.length; j++ ){
if(viewstoHide[j].getVisibility() == View.VISIBLE){ //// syntax error on this line
viewstoHide[j].setVisibility(View.GONE); //// syntax error on this line
}
}
System.out.println("VIEWS TO HIDE : " + Arrays.toString(viewstoHide));
}
Your viewstoHide array does not contain ui elements, so you cannot use those methods. In order to use those methods, change the type of your array or add ui elements like LinearLayout or Radiogroup.
It's not a very good practice to add different types of ojects in your array because when you loop through the array of objects and you if want a to use a specific method on all elements, you can have only one different element and your loop will break. So in order to solve your problem, please use specific type for each array or add only ui elements. Good preactice is to verify if your elements are instanceof desired classes. Hope it helps.
Try making viewsToToggle an Array of LinearLayout instead of an Array of Object.
Same goes for viewsToHide.

Assigning New Object to a Generic Array Index

I'm POSITIVE that my title for this topic is not appropriate. Let me explain. The purpose of this is to duplicate a "Profile" application, where I have a profile and so would you. We both have our own followers and in this example, we both follow each other. What this method is needed to return is a cross reference based on whom you follow that I do not. I need this method to return to me a recommended Profile object that I do not already have in my array. Right now I'm having a difficult time with one line of code within a particular method.
One of my classes is a Set class that implements a SetInterface (provided by my professor) and also my Profile class that implements a ProfileInterface which was also provided. In my code for the Profile class, I have the following object: private Set<ProfileInterface> followBag = new Set<ProfileInterface>(); which utilizes the Array bag methods from my Set class with the ProfileInterface methods I've made.
Here is the method (not complete but can't move further without my problem being explained):
public ProfileInterface recommend(){
Set<ProfileInterface> recommended;
ProfileInterface thisProfile = new Profile();
for(int index = 0; index < followBag.getCurrentSize(); index++){
Set<ProfileInterface> follows = followBag[index].toArray();
for(int followedFollowers = 0; followedFollowers < follows.getCurrentSize(); followedFollowers++) {
if()
//if Profile's do not match, set recommended == the Profile
}
}
return recommended;
}
The purpose of this method is to parse through an array (Profile as this example) and then take each of those sub-Profiles and do a similar action. The reason for this much like "Twitter", "Facebook", or "LinkedIn"; where each Profile has followers. This method is meant to look through the highest Profiles follows and see if those subProfiles have any followers that aren't being followed by the highest one. This method is then meant to return that Profile as a recommended one to be followed. This is my first dealing with Array Bag data structures, as well as with generics. Through "IntelliJ", I'm receiving errors with the line Set<ProfileInterface> follows = followBag[index].toArray();. Let me explain the reason for this line. What I'm trying to do is take "my" profile (in this example), and see who I'm following. For each followed profile (or followBag[index]) I wish to see if followBag[index][index] == followBag[index] and continue to parse the array to see if it matches. But, due to my confusion with generics and array bag data structures, I'm having major difficulties figuring this out.
I'd like to do the following:
//for all of my followers
//look at a particular followed profile
//look at all of that profile's followers
//if they match one of my followers, do nothing
//else
//if they don't match, recommend that profile
//return that profile or null
My problem is that I do not know how to appropriately create an object of a Profile type that will allow me to return this object
(in my method above, the line Set<ProfileInterface> follows = followBag[index].toArray();)
I'm trying to make an index of my Profile set to an object that can later be compared where my difficulties are. I'd really appreciate any insight into how this should be done.
Much appreciated for all help and Cheers!
When you do:
Set<ProfileInterface> follows = followBag[index].toArray();
you're trying to use Set as Array. But you can't.
Java will not allow, because Set and Array are different classes, and Set does not support [] syntax.
That is why you get error. For usefollowBag as Array you have to convert it:
ProfileInterface[] profileArray = followBag.toArray(new ProfileInterface[followBag.size()]);
for(int i=0; i<profileArray.length; i++){
ProfileInterface profile = profileArray[i];
//do what you would like to do with array item
}
I believe, in your case, you don't need assign Set object to generic Array at all. Because you can enumerate Set as is.
public class Profile {
private Set<ProfileInterface> followBag = new HashSet<Profile>();
...
public Set<ProfileInterface> recommended(){
Set<ProfileInterface> recommendSet = new HashSet<ProfileInterface>();
for(Profile follower : followBag){
for(Profile subfollower : follower.followBag){
if(!this.followBag.contains(subfollower)){
recommendSet.add(subfollower);
}
}
}
return recommendSet;
}
}
I also added possibility of returning list of recommended profiles, because there is may be several.

android setText() multiple textViews

Hello I have 3 Type of textViews in my Layout with same Dynamic text but there is only one Difference between them i.e. . Postion . I wanted to show and hide them according to Button Click . but the problem problem occurs when I have to write the same code for five Different TextViews with only one TEXT . Kindly Suggest me Efficient way which could reduce the number of line in my JAVA code.
temperature.setText(temp);
txt.setText(Name);
descptxt.setText(descp);
temperature3.setText(temp);
txt3.setText(Name);
descptxt3.setText(descp);
temperature4.setText(temp);
txt4.setText(Name);
descptxt4.setText(descp);
the number of TextViews will be increase in Future . I am worried about writing same Boiler Plate Code again and Agian
create a function like this:
void setText(String name,String temp,String descp){
for(int i=0;i<txt.size();i++){
temperature.get(i).setText(temp);
txt.get(i).setText(Name);
descptxt.get(i).setText(descp);
}
}
Also instead of creating different variables for each textview create an array of it.
ArrayList<TextView> temperature=new ArrayList<TextView>();
temperature.add((TextView)findViewById(<id>));
//Same for rest of them
And when you want to change text:
setText("","","");
Store each objects in a array ie. temperature objects in a separate array. txt objects in a separate array and descp objects in a separate array.
create a method like
public void setTexts(String temp,String name,String desc){
for(TextView temperature : temperatureArray){
//Change for loop declaration according to your code
//set text for temperature
temperature.setText(temp);
}
for(TextView txt : txtArray){
//Change for loop declaration according to your code
//set text for txt
txt.setText(name);
}
for(TextView descp : descpArray){
//Change for loop declaration according to your code
//set text for descp
descp.setText(desc);
}
}
If your TextViews are logically grouped together, you might want to create one compound View containing all of them:
public class TemperatureView extends ViewGroup { //or whichever layout you use
private TextView textView1;
private TextView textView2;
private TextView textView3;
public void setData(TemperatureData data) {
textView1.setText(...);
textView2.setText(...);
textView3.setText(...);
}
}
In my opinion, this is the most elegant solution in such situation.
You can use alternative in which u can apply loop over childcount of parent layout instead of finding using findViewById.and then using instance of operator ,you can find textviews on which u want to perform the task.

Use a reference inside an ArrayList to call a method, and change the current state of the referenced object?

Maybe this just isn't possible but what I'm trying to do is change the visibility of multiple elements in a GUI at the same time using an ArrayList to reference to them sort of dynamically. The objects are created by themselves in another method.
Both oldScreen.setVisible(false); and oldScreen<1>.setVisible(false); statements cause errors. I had a hunch my idea wouldn't work out so well.
Here is basically what i have, any way i can achieve this?
private void initScreens() {
// I create some ArrayLists as "screensets" of sorts and put some GUI elements in there
ArrayList startScreen = new ArrayList();
ArrayList lostScreen = new ArrayList();
ArrayList playScreen = new ArrayList();
startScreen.add(startB);
startScreen.add(exitB);
lostScreen.add(yl1);
lostScreen.add(yl2);
lostScreen.add(yl3);
lostScreen.add(yl4);
lostScreen.add(yl5);
}
private void changeScreen(ArrayList oldScreen,ArrayList newScreen) {
// now i try to create a handy method to handle the length of the arrays itself, so if
i need to make changes to screens I just add them to there array. They are then easily
displayed, and hidden when told.
int os = oldScreen.size();
int ns = newScreen.size();
for (int i = os; i > 0; i--){
oldScreen<i>.setVisible(false);
oldScreen<1>.setVisible(false);
}
That's invalid syntax.
You're trying to write
oldScreen.get(i)
You should also use generics (ArrayList<Screen>) to avoid casting.

Java: linked list of items problem

I have used linked lists before with Strings, doubles, etc., and they always worked exactly as expected. But now I am forming a linked list of items, and whenever I add a new element to the list, all objects in the list apparently become equal to the last object.
The essential code is as below:
import java.util.*;
public class Global
{
static public LinkedList<StockInfo> DiaryStocks = new LinkedList<StockInfo>();
static public class StockInfo //info related to each stock in diary
{
String recordDate;
String ticker;
int status;
String buyDate;
String sellDate;
double buyPrice;
double sellPrice;
double nmbrShares;
}//StockInfo
//The following function places the Diary data for a stock in the arraylist
static public void AddDiaryData(StockInfo thisdata)
{
String tckr;
int i;
DiaryStocks.add(thisdata);
for (i = 0; i < DiaryStocks.size(); i++) //this is debug code
{
tckr = DiaryStocks.get(i).ticker;
}
}
}
As I said, when single stepping through the debug code near the bottom, each time I add a new item to the list, the list size grows as it should, but the tckr item only corresponds to the last item added.
Any insights into this puzzle would be greatly appreciated.
John Doner
The problem is outside the code your provide. It is most likely that you are adding the same instance of StockInfo. Perhaps you have something like:
StockInfo info = new StockInfo();
for (...) {
info.setFoo(..);
info.setBar(..);
AddDiaryData(info);
}
You should not reuse instances like that. You should create a new instance each time.
As a sidenote - method names in Java should start with lowercase letter.
From the symptoms you are describing, it seems as if you are always adding a reference to the same StockInfo object instance to your list, rather than a reference to a new copy each time.
When that object is updated with the contents of the new entry, all list entries appear to change to reflect that latest entry.
This problem lies outside the code snippet that you posted, perhaps in the caller of the AddDiaryData method.
Ooops.
Deep Copy please search it
DiaryStocks.add(thisdata);
you should create new StockInfo() then add to the list otherwise you add the reference and it equalize all the reference of items to the last one

Categories