Я пытаюсь добавить Button
динамически в onPostExecute
методом AsyncTask
. Я делаю это внутри класса, который расширяет Fragment
. Я могу использовать этот код для динамического создания Button
вне AsyncTask
:
public class Tab2Fragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
LinearLayout theLayout = (LinearLayout) inflater.inflate(R.layout.tab2, container, false);
Context mFragmentContext=getActivity().getApplicationContext();
Button btn=new Button(mFragmentContext);
btn.setText("Hello Button");
RelativeLayout.LayoutParams paramsd = new RelativeLayout.LayoutParams(150,30);
paramsd.height = paramsd.WRAP_CONTENT;
paramsd.width = paramsd.WRAP_CONTENT;
btn.setLayoutParams(paramsd);
theLayout.addView(btn);
Button test = (Button)theLayout.findViewById(R.id.test41);
test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.v("response", "Button Clicked");
new loadSomeStuff().execute();
Intent log = new Intent();
log.setClass(getActivity(), Assignment.class);
startActivity(log);
}
});
return theLayout;
}
// Method to load stuff using async task. Grabs information from URL and
// calls read stream
public class loadSomeStuff extends AsyncTask<String, Integer, String> {
protected String doInBackground(String... arg0) {
try {
int limit = 100;
String accessToken = "";
URL url = new URL( "SomeSite" + accessToken
+ "&status=active" + "&limit=" + limit);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Accept", "application/json");
readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute( String result ) {
super.onPostExecute(result);
Context mFragmentContext=getActivity().getApplicationContext();
Button btn=new Button(mFragmentContext);
btn.setText("Hello Button");
RelativeLayout.LayoutParams paramsd = new RelativeLayout.LayoutParams(150,30);
paramsd.height = paramsd.WRAP_CONTENT;
paramsd.width = paramsd.WRAP_CONTENT;
btn.setLayoutParams(paramsd);
//theLayout.addView(btn);
Log.v("response", "on post biatch");
}
}
// Processes information from URL and prints it in format
private void readStream(InputStream in) throws JSONException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();
String total_results = new JSONObject(line).getJSONObject(
"response").getString("total_results");
int assignCount = Integer.parseInt(total_results.toString());
Log.v("response", total_results);
JSONObject data;
for (int i = 0; i < assignCount; i++) {
data = new JSONObject(line).getJSONObject("response");
String id = data.getJSONArray("data").getJSONObject(i).getString("id");
String title = data.getJSONArray("data").getJSONObject(i).getString("title");
Log.v("response", title);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Проблема в том, что когда я пытаюсь поместить этот код в onPostExecute
из AsyncTask
, addview(btn)
имеет ошибки, потому что Layout
не определен. Я не могу понять, как передать Layout
. Есть ли способ захватить Layout
деятельности с каким-то встроенным методом?
Почему бы вам не добавить конструктор в класс loadSomeStuff
? На Конструктора, передать View
, что вы хотите добавить Button
в.
public class loadSomeStuff extends AsyncTask<String, Integer, String> {
private View view;
public loadSomeStuff(View v) {
view = v;
}
public String doInBackground(String... strings) {
//...
}
public void onPostExecute(String result) {
//...
view.addView(btn);
}
}
Это работает для меня, чтобы добавить RelativeLayout программно и вставить в него кнопку:
RelativeLayout.LayoutParams yourlayout = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
yourlayout.addRule(RelativeLayout.ALIGN_PARENT_TOP,anotherview.getId());
yourlayout.addView(yourbutton, yourlayout);
Я настоятельно рекомендую вам использовать setId() и назначать уникальный идентификатор для каждого представления, если вы работаете с динамическими макетами, а не со статическим XML. Это необходимо, чтобы позиционировать представление, используя другие ссылки на представления.
Вы можете использовать Handler; add the following to the main
Handler; add the following to the main
деятельность:
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case 0:
Context mFragmentContext=getActivity().getApplicationContext();
Button btn=new Button(mFragmentContext);
btn.setText("Hello Button");
RelativeLayout.LayoutParams paramsd = new RelativeLayout.LayoutParams(150,30);
paramsd.height = paramsd.WRAP_CONTENT;
paramsd.width = paramsd.WRAP_CONTENT;
btn.setLayoutParams(paramsd);
// addView(btn) in your LinearLayout
break;
}
}
};
Передайте Handler
с помощью AsyncTask
и в onPostExecute(String result)
используйте Handler
следующим образом:
public void onPostExecute(String result) {
Message msg = new Message();
msg.what = 0;
handler.sendMessage(msg);
}
Вы можете создать другое событие в классе Handler
и выбрать вид с msg.what
.
Надеюсь, это помогло.
Async Task
находится в одном классе, вы можете сделать ее общедоступной. В другом случае вы можете передать свойLayout
как конструктор вашейAsync Task