0

image

Room b lamp 2 turn on but status turn green on room a lamp 2 status

I created my mainlayout using Layoutinflater from another layout. This will add more control dynamically. I can create as many sub layout dynamically within my mainlayout. The problem is that how to access particular textview in current sublayout operation. Eg if I press button ON from lamp2 in Room b, only status next to it will turn green or red.

This is the my mainactivity that load my layouts

public class MainActivity extends Activity {

Button buttonAdd;
LinearLayout container;
SQLiteDatabase db1;
String sa;
String sb;
TextView txtSta1;
TextView txtSta2;
//TextView txtSta1;
//TextView txtSta2;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    container = (LinearLayout) findViewById(R.id.container);
    createDB();
    allControl();
    LayoutTransition transition = new LayoutTransition();
    container.setLayoutTransition(transition);
}

public void addLayoutControl(String a, String room, String b, String c, final int d) {
    LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View addView = layoutInflater.inflate(R.layout.row, null);
    final TextView txtIP = (TextView) addView.findViewById(R.id.textIP);
    final TextView txtRoom = (TextView) addView.findViewById(R.id.textRoom);
    final TextView txtS1 = (TextView) addView.findViewById(R.id.tvS1);
    final TextView txtS2 = (TextView) addView.findViewById(R.id.tvS2);
    txtSta1 = (TextView) addView.findViewById(R.id.textSta1);
    txtSta2 = (TextView) addView.findViewById(R.id.textSta2);
    txtIP.setText(a);
    txtRoom.setText(room);
    txtS1.setText(b);
    txtS2.setText(c);

    new OnStatusSwitch().execute(a);
    Button buttonOn1 = (Button) addView.findViewById(R.id.on1);
    buttonOn1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            new OnSwitch1on2g().execute(txtIP.getText().toString(),"b1on");             
        }
    });
    Button buttonOn2 = (Button) addView.findViewById(R.id.on2);
    buttonOn2.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            new OnSwitch1on2g().execute(txtIP.getText().toString(),"b2on");

        }
    });

    Button buttonOff1 = (Button) addView.findViewById(R.id.off1);
    buttonOff1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            new OnSwitch1off2g().execute(txtIP.getText().toString(),"b1off");
        }
    });
    Button buttonOff2 = (Button) addView.findViewById(R.id.off2);
    buttonOff2.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            new OnSwitch1off2g().execute(txtIP.getText().toString(),"b2off");
        }
    });

    container.addView(addView, 0);

}

public void callAdd(View v) {
    Intent intent = new Intent(this, AddNode.class);
    startActivity(intent);
}

public void createDB() {
    db1 = this.openOrCreateDatabase("dbcontrol", MODE_PRIVATE, null);
    String sqlcreate = "CREATE TABLE IF NOT EXISTS node" + "(TYPE VARCHAR, IP VARCHAR,LOCATION VARCHAR,S1 VARCHAR, S2 VARCHAR);";
    db1.execSQL(sqlcreate);
}

public void allControl() {
    String sqlSearch = "SELECT * FROM node";
    String sIP = "";
    Cursor c = db1.rawQuery(sqlSearch, null);
    if (c.getCount() > 0) {
        c.moveToFirst();
        //while (!c.()){
        for (int i = 0; i < c.getCount(); i++) {
            sIP = c.getString(c.getColumnIndex("IP"));
            String sLOC = c.getString(c.getColumnIndex("LOCATION"));
            String sS1 = c.getString(c.getColumnIndex("S1"));
            String sS2 = c.getString(c.getColumnIndex("S2"));
            addLayoutControl(sIP, sLOC, sS1, sS2,i);
            c.moveToNext();
        }
    }
}

class OnSwitch1on2g extends AsyncTask<String, String, String> {
    String serverip,cond;
    @Override
    protected void onPreExecute() {
    }

    @Override
    protected String doInBackground(String... params) {
        serverip = params[0];
        cond = params[1];
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://" + serverip + ":88/operation?");

        try {
            // Add your data
            List<BasicNameValuePair> nameValuePairs = new ArrayList<BasicNameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("ope", cond));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            httpclient.execute(httppost);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }

    protected void onPostExecute(String ab) {
        // new OnStatusSwitch().execute();
        //Toast.makeText(getApplicationContext(), "Success "+serverip+ " button "+cond , Toast.LENGTH_SHORT).show();
        new OnStatusSwitch().execute(serverip);
    }

}

class OnSwitch1off2g extends AsyncTask<String, String, String> {
    String serverip,cond;
    @Override
    protected void onPreExecute() {
    }

    @Override
    protected String doInBackground(String... params) {
        serverip = params[0];
        cond = params[1];
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://" + serverip + ":88/operation?");

        try {
            // Add your data
            List<BasicNameValuePair> nameValuePairs = new ArrayList<BasicNameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("ope", cond));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            httpclient.execute(httppost);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    } 

    protected void onPostExecute(String ab) {
        // new OnStatusSwitch().execute();
        new OnStatusSwitch().execute(serverip);
        //Toast.makeText(getApplicationContext(), "Success "+serverip+ " button "+cond , Toast.LENGTH_SHORT).show();
    }
}

class OnStatusSwitch extends AsyncTask<String, String, String> {
    JSONParser jsonparser = new JSONParser();
    JSONObject jobj = null;
    String pina;
    String pinb;

    @Override
    protected String doInBackground(String... params) {
        try {
            String serverip = params[0];
            String url = "http://" + serverip + ":88/getstatus";
            jobj = jsonparser.makeHttpRequest(url);
            pina = jobj.getString("pin1");
            pinb = jobj.getString("pin2");
            runOnUiThread(new Runnable() {
                public void run() {
                    if (pina.equals("0")) {
                        txtSta1.setBackgroundColor(Color.GREEN);
                    }else{
                        txtSta1.setBackgroundColor(Color.RED);
                    }
                    if (pinb.equals("0")) {
                        txtSta2.setBackgroundColor(Color.GREEN);                        
                    }else{
                        txtSta2.setBackgroundColor(Color.RED);
                    }
                }

            });
            return pina+pinb;
        } catch (Exception e2) {
        }
        return null;
    }

    protected void onPostExecute(String ab) {
        sa =  ab.substring(0,1);
        sb =  ab.substring(1);

    }       
}

This really bugging me..need help to solve this problem..not quite familiar with layout control.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Hanis
  • 309
  • 1
  • 6
  • 15
  • Are you familiar with the concepts of MVC or MVP Pattern? Because that is essentially what you need. You need a `ControlPanel` class that can reference itself from all its components – OneCricketeer Jun 11 '16 at 06:08
  • For some guidance, you might want a custom View class -- https://developer.android.com/training/custom-views/index.html – OneCricketeer Jun 11 '16 at 06:13
  • I'm not familiar with it. I tried provide id for each component...but seems more complicated for me...I can only do reference within the onlayoutcontrol. Any other way this can be done with overhauling my code.. – Hanis Jun 11 '16 at 07:12

1 Answers1

0

First, I recommend one ToggleButton or Switch instead of 2 individual buttons, but if you would like to "bind" the state of a TextView to the button, you can simply create a custom ClickListener class.

class MyCheckChangedListener implements CompoundButton.OnCheckedChangeListener {
    private TextView tv;

    public MyCheckChangedListener(TextView tv) {
        this.tv = tv;
    }

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // TODO: if (isChecked) { do network operation }
        tv.setBackgroundColor(isChecked ? Color.GREEN : Color.RED);
    }
};

To use, do like so

TextView txtStatus = (TextView) findViewById(R.id.status);
ToggleButton toggle = (ToggleButton) findViewById(R.id.togglebutton);
toggle.setOnCheckedChangeListener(new MyCheckChangedListener(txtStatus));

Though, the nice thing about the ToggleButton is that you really don't even need the TextView, you can see the "status" by looking at the state of the button itself.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I've tried toggle button..but since I'm using asynctask threads (request status from webserver) to read status so this won't work (i presume).. everytime i recall the status to set the toggle button status seems to run the thread request status operation again. This is very inconvenient. I did stop and run the listener for toggle button but seems make it worst. – Hanis Jun 11 '16 at 07:30
  • It should only trigger once per checked state. The only difference between it and a regular button is that is that it has 2 states and you need `CompoundButton.OnCheckedChangeListener` instead of `View.OnClickListener` – OneCricketeer Jun 11 '16 at 07:36
  • I would also suggest your server send back the status as part of the POST request so you don't have to make two network requests to get the status – OneCricketeer Jun 11 '16 at 07:38
  • yes.. i now that..but again coming back to my problem is..the view it self. When i create custom layout for second or third or forth room, I cannot access status textview from the selected button operation. It will always select the status textview at the beginning of my layout. I need to request for the switch status for now and then so to reach every status textview is important. hope you can understand..thanks for your reply.. – Hanis Jun 11 '16 at 07:40
  • regarding POST..yes i'm thinking also about that..but still i need to check the status of every switch available at oncreate. so its better to have one thread check the status of every switch available first and use that once..and also problem still remain..since i cannot access status textview from spesific sub layout in my main activity.. – Hanis Jun 11 '16 at 07:42
  • I think I understand what you want. So, you need to update the TextView (any TextView for any layout) from the AsyncTask. To do so, you need to implement [callbacks in your AsyncTask](https://stackoverflow.com/questions/26202568/android-pass-function-reference-to-asynctask) – OneCricketeer Jun 11 '16 at 07:45
  • Ya I'm also looking for a way asynctask class that can return value..that would be great. I can call from button click method and set it from there.. – Hanis Jun 11 '16 at 07:48
  • Read the link, or you can even use [Volley](https://developer.android.com/training/volley/simple.html) and other libraries for simpler network requests than AsyncTask – OneCricketeer Jun 11 '16 at 07:50
  • Later with volley... just get me clear on this callback...If i put the protected void onPostExecute(String ab) { super.onPostExecute(ab); } How do I call the value ab from my new OnStatusSwitch().execute(a); ? – Hanis Jun 11 '16 at 08:08
  • No, don't worry about the `super.onPostExecute`. The important piece is `this.taskListener.onFinished(result);` Where `result` is going to be the data you want sent back to the spot of code that you called the `execute()` method from – OneCricketeer Jun 11 '16 at 08:17