Boo Boo - 4 months ago 22
Android Question

Cannot update dynamic buttons from a Json populated Array

****Working code posted****

I am trying to update buttons where the text will be dynamically programmed from an ArrayList. The data is being retrieved from mySQL. I can get the data in and fill the array with what I need (familyMemberArray). However for some reason when the information is gathered, the program does not go on to implementing the "trending" array or the rest of the layout programming, after the array information has been produced.

I need to formulate the data first so I know how big the array is to create the amount of buttons necessary. If I call in a basic String array it populates the buttons just fine. I remember being stuck on this problem on a uni project and ended up giving up because I just could not get it to work and time was ticking. Please put me out of my misery

public class TrendingMealsFragment extends Fragment {

private TableRow tr;

//SQLite Database
private static final String SELECT_SQL = "SELECT * FROM family_account";
private SQLiteDatabase db;
private Cursor c;
private static final String DATABASE_NAME = "FamVsFam.db";

// Logging
private final String TAG = this.getClass().getName();

private static final String EXTRA_CHALLENGE_ID = "boo.famvsfam.challenge_id";
//Results
private JSONArray resultFamilyMember;
private String dbID;
public static final String JSON_ARRAY = "result";
private List<String> familyMemberArray;

ArrayAdapter<String> adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

openDatabase();

setHasOptionsMenu(true);

c = db.rawQuery(SELECT_SQL, null);
c.moveToFirst();
getRecords();

}

protected void openDatabase() {

db = getActivity().openOrCreateDatabase(DATABASE_NAME, android.content.Context.MODE_PRIVATE, null); // db = SQLiteDatabase.openOrCreateDatabase("FamVsFam", Context.MODE_PRIVATE, null);
}

protected void getRecords() {
dbID = c.getString(0);
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

getData();

/** Declaring an ArrayAdapter to set items to ListView */
familyMemberArray = new ArrayList<>();
//Menu
setHasOptionsMenu(true);
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);

View view = inflater.inflate(R.layout.activity_resturants, container, false);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.getSupportActionBar();

/**
ArrayList<String> trending1 = new ArrayList<String>() {
{
add("one");
add("two");
add("three");
add("four");
add("five");
add("six");
add("seven");
add("eight");
add("nine");
add("ten");
add("eleven");
}
};*/

ArrayList<String> trending = new ArrayList<String>() {
{

for(int i = 0; i < familyMemberArray.size() ; i++){

add(familyMemberArray.get(i));

}}
};

// LAYOUT SETTING 1
RelativeLayout root = new RelativeLayout(getActivity());
// root.setId(Integer.parseInt(MEAL_SELECTION_ID));
LayoutParams param1 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
root.setFitsSystemWindows(true);
}
root.setLayoutParams(param1);

//LAYOUT SETTINGS 2 - TOP BANNER - WITH PAGE HEADING
RelativeLayout rLayout1 = new RelativeLayout(getActivity());
LayoutParams param2 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
float topBannerDim = getResources().getDimension(R.dimen.top_banner);
param2.height = (int) topBannerDim;
param2.addRule(RelativeLayout.BELOW, root.getId());
int ele = (int) getResources().getDimension(R.dimen.elevation);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
rLayout1.setElevation(ele);
}
rLayout1.setBackgroundColor(Color.parseColor("#EEEBAA"));
rLayout1.setLayoutParams(param2);

//TEXT VIEW
TextView text1 = new TextView(getActivity());
text1.setText(R.string.diet_req);
LayoutParams param3 = new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
param3.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
text1.setTextColor(Color.parseColor("#8A1F1D"));
text1.setTypeface(Typeface.DEFAULT_BOLD);
text1.setLayoutParams(param3);

//LAYOUT SETTINGS 4
RelativeLayout rLayout4 = new RelativeLayout(getActivity());
LayoutParams param5 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
topBannerDim = getResources().getDimension(R.dimen.top_banner);
param5.height = (int) topBannerDim;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
param5.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.ALIGN_START);
}
param5.addRule(RelativeLayout.BELOW, rLayout1.getId());
rLayout4.setId(R.id.id_relative_4);
rLayout4.setBackgroundColor(Color.parseColor("#EEEBAA"));
rLayout4.setLayoutParams(param5);

//LAYOUT SETTINGS 5
TableLayout rLayout5 = new TableLayout(getActivity());
rLayout5.setOrientation(TableLayout.VERTICAL);
LayoutParams param7 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
param7.addRule(RelativeLayout.BELOW, rLayout4.getId());
rLayout5.setBackgroundColor(Color.parseColor("#EEEBAA"));

rLayout5.setLayoutParams(param7);
// List<ToggleButton> togButtStore = new ArrayList<ToggleButton>();

int i = 0;
while (i < trending.size()) {
if (i % 3 == 0) {
tr = new TableRow(getActivity());
rLayout5.addView(tr);
}
ToggleButton toggleBtn = new ToggleButton(getActivity());
toggleBtn.setText(trending.get(i));
toggleBtn.setId(i);
toggleBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Context context = getActivity().getApplicationContext();

CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
} else {
// The toggle is disabled
}
}
});
tr.addView(toggleBtn);
i++;
}

//LAYOUT SETTINGS 6
FrameLayout youBeenFramed = new FrameLayout(getActivity());
LayoutParams param8 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
param8.addRule(RelativeLayout.BELOW, rLayout5.getId());
youBeenFramed.setBackgroundColor(Color.parseColor("#EEEBAA"));

root.addView(youBeenFramed);
root.addView(rLayout1);
rLayout1.addView(text1);
root.addView(rLayout4);
root.addView(rLayout5);
getActivity().setContentView(root);



return view;
}

public void getData() {
//// TODO: 03/08/2016 Progress Dialogs : on getting data
// final ProgressDialog loading = ProgressDialog.show(getActivity(), "Loading Data", "Please wait...", false, false);

StringRequest strReq = new StringRequest(Request.Method.POST,
PHPConfigURLS.URL_ALL_FAMILY_MEMBERS, new Response.Listener<String>() {

@Override
public void onResponse(String response) {

Log.d(TAG, "Login Response: " + response.toString());
JSONObject j = null;

try {

// loading.dismiss();
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
resultFamilyMember = j.getJSONArray(JSON_ARRAY);
//Calling method getStudents to get the students from the JSON Array
getDBFamilyName(resultFamilyMember);

} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {

@Override
public void onErrorResponse(VolleyError error) {

}
}) {
@Override
protected Map<String, String> getParams() {

String id = dbID;
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
// params.put("email", email);
// params.put("password", password);

return params;
}
};

RequestQueue requestQueue = Volley.newRequestQueue(getActivity());

//Adding request to the queue
requestQueue.add(strReq);
}

private void getDBFamilyName(JSONArray j) {

//Traversing through all the items in the json array
for (int i = 0; i < j.length(); i++) {

FamilyAccount familyMember = new FamilyAccount();

try {
//Getting json object
JSONObject json = j.getJSONObject(i);

familyMember = new FamilyAccount();
familyMember.setName(json.getString("name"));
familyMember.setID(json.getInt("id"));

} catch (JSONException e) {
e.printStackTrace();
}
//Adding the title of the challenge to array list
familyMemberArray.add(familyMember.getName());
}

}

}


Thanks in advance

Answer

for some reason when the information is gathered, the program does not go on to implementing the "trending" array or the rest of the layout programming, after the array information has been produced.

That's because the layout doesn't "dynamically" update when you call this when the request finishes.

familyMemberArray.add(familyMember.getName());

You'll have to clear the view, and redo all the view adding again, or "extract" all the view generation code into it's own method that you can call with the parameter of your ArrayList.

Basically, everything between // LAYOUT SETTING 1 and return view (non-inclusive) needs to be moved into a public void generateView(ArrayList<String> familyMemberArray) method that can optionally return the root View that was generated, if necessary.

Then, at the end of getFamilyName(), outside the loop, call that method with your ArrayList.

I need to formulate the data first so I know how big the array is to create the amount of buttons necessary.

I'm not sure I see where you are doing that. Unless you mean here

while (i < trending.size()) {

Which, instead, trending is an entirely different list reference than familyMemberArray, so it won't update either. Though, it contains the exact same data?

ArrayList<String> trending = new ArrayList<String>() {
    {
        for(int i = 0; i < familyMemberArray.size() ; i++){
            add(familyMemberArray.get(i));
    }}
};

That block of code looks a bit odd, considering the ArrayList constructor already provides that functionality

ArrayList<String> trending = new ArrayList<String>(familyMemberArray);