【问题标题】:Accessing component within layout inflater在布局充气器中访问组件
【发布时间】:2016-06-11 06:02:54
【问题描述】:

房间 b 灯 2 亮,但状态在房间 a 灯 2 状态上变为绿色

我使用另一个布局中的 Layoutinflater 创建了我的主布局。这将动态添加更多控制。我可以在主布局中动态创建尽可能多的子布局。问题是如何在当前子布局操作中访问特定的文本视图。例如,如果我在房间 b 的灯 2 上按下按钮 ON,只有旁边的状态会变成绿色或红色。

这是我加载布局的主要活动

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);

    }       
}

这真的让我很烦恼..需要帮助来解决这个问题..不太熟悉布局控制。

【问题讨论】:

  • 您熟悉 MVC 或 MVP 模式的概念吗?因为这本质上就是你所需要的。你需要一个ControlPanel 类,它可以从它的所有组件中引用自己
  • 对于一些指导,您可能需要一个自定义 View 类 -- developer.android.com/training/custom-views/index.html
  • 我不熟悉。我尝试为每个组件提供 id...但对我来说似乎更复杂...我只能在 onlayoutcontrol 中进行引用。任何其他方式都可以通过彻底检查我的代码来完成..

标签: android


【解决方案1】:

首先,我推荐一个 ToggleButton or Switch 而不是 2 个单独的按钮,但是如果您想将 TextView 的状态“绑定”到按钮,您可以简单地创建一个自定义 ClickListener 类。

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);
    }
};

要使用,就这样做

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

不过,ToggleButton 的好处在于您甚至不需要 TextView,您可以通过查看按钮本身的状态来查看“状态”。

【讨论】:

  • 我试过切换按钮..但是因为我使用 asynctask 线程(来自网络服务器的请求状态)来读取状态,所以这不起作用(我想)..每次我回忆状态设置切换按钮状态似乎再次运行线程请求状态操作。这是非常不方便的。我确实停止并运行了切换按钮的监听器,但似乎让它变得最糟糕。
  • 每个检查状态应该只触发一次。它和普通按钮的唯一区别是它有两种状态,你需要CompoundButton.OnCheckedChangeListener而不是View.OnClickListener
  • 我还建议您的服务器将状态作为 POST 请求的一部分发回,这样您就不必发出两个网络请求来获取状态
  • 是的..我现在那个..但再次回到我的问题是..自己的看法。当我为第二个或第三个或第四个房间创建自定义布局时,我无法从选定的按钮操作访问状态文本视图。它总是会在我的布局开始时选择状态文本视图。我需要不时请求切换状态,因此达到每个状态 textview 很重要。希望你能理解..谢谢你的回复..
  • 关于 POST..是的,我也在考虑这个问题..但我仍然需要检查 oncreate 上每个可用开关的状态。所以最好让一个线程首先检查每个可用开关的状态并使用一次..而且问题仍然存在..因为我无法从我的主要活动中的特定子布局访问状态文本视图..
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多