Add text view dynamically inside a tab (Android) - android

I am trying to add a textview inside a tab dynamically. using this code
Oncreate()
{
OA.loaderShow(this); //Loader display
new Thread(new Runnable(){
public void run()
{
Looper.prepare();
fetchDocs();
OA.loaderHide(); //Loader Hide
Looper.loop();
}
}).start();
}
fetchDocs()
{
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
TextView text = new TextView(this);
text.setText(mytext);
layout.addView(text);
}
I am getting this error "Only the original thread that created a view hierarchy can touch its view".
Please Help.

Put above inside the following block
runOnUiThread(new Runnable() {#Overridepublic void run() {//your code here}}

Try using a handler like this:
EDIT:
protected static final int SET_TEXTVIEW = 0;
Oncreate()
{
OA.loaderShow(this); //Loader display
new Thread(new Runnable(){
public void run()
{
Looper.prepare();
handler.sendMessage(handler.obtainMessage(SET_TEXTVIEW));
OA.loaderHide(); //Loader Hide
Looper.loop();
}
}).start();
}
public Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SET_TEXTVIEW :
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
TextView text = new TextView(this);
text.setText(mytext);
layout.addView(text);
}
}
};

Add this in the onCreate method rather than adding from else where.

Related

Issues Using Android LinearLayout

I have a LinearLayout, containing one EditText and one TextView. My ConsoleWindow is running in a loop, and I would like to update the TextView in each Iteration.
The problem is that I may initialize the EditText only once (otherwise it is inaccessible) and also the LinearLayout may only be initialized once (otherwise it would remove the EditText).
I cannot put the LinearLayout and the EditText in an if-statement:
if (firstRun) {
// initialize LinearLayout and EditText
firstRun = false;
}
// TEXTVIEW
TextView tv = new TextView(getApplicationContext())
tv.setText(dataStringTot);
layout.addView(tv); // "Qualifier must be an Expression."
because the IDE Returns at layout.addView(tv); : "Qualifier must be an expression."
My Code:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getInetContent();
}
getInetContent() { // would be a thread
// getting data...
Bundle b = new Bundle();
b.putString("StringNMEA", NMEA);
Message m = mhandler.obtainMessage();
m.setData(b);
mhandler.sendMessage(m);
}
Handler handler = new Handler() {
public void handleMessage(Message msg) {
String dataString = "";
Bundle bundle = msg.getData();
if (bundle.containsKey("display")) {
ConsoleWindow(dataString);
}
}
}
private void ConsoleWindow(String dataString) {
// LINEAR LAYOUT
LinearLayout layout = new LinearLayout(this);
setContentView(layout);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setBackgroundColor(Color.parseColor("#000000")); // black
// EDITTEXT
EditText et = new EditText(getApplicationContext());
et.setHint("Enter Command");
layout.addView(et);
// TEXTVIEW
TextView tv = new TextView(getApplicationContext());
tv.setText(dataStringTot);
layout.addView(tv);
}
}
My Code with if-statement:
public boolean firstRun = true;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getInetContent();
}
getInetContent() { // would be a thread
// getting data...
Bundle b = new Bundle();
b.putString("StringNMEA", NMEA);
Message m = mhandler.obtainMessage();
m.setData(b);
mhandler.sendMessage(m);
}
Handler handler = new Handler() {
public void handleMessage(Message msg) {
String dataString = "";
Bundle bundle = msg.getData();
if (bundle.containsKey("display")) {
ConsoleWindow(dataString);
}
}
}
private void ConsoleWindow(String dataString) {
if (firstRun) {
// initialize LinearLayout and EditText:
// LINEAR LAYOUT
LinearLayout layout = new LinearLayout(this);
setContentView(layout);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setBackgroundColor(Color.parseColor("#000000")); // black
// EDITTEXT
EditText et = new EditText(getApplicationContext());
et.setHint("Enter Command");
layout.addView(et);
firstRun = false;
}
// TEXTVIEW
TextView tv = new TextView(getApplicationContext());
tv.setText(dataStringTot);
layout.addView(tv);
}
}
How could I fix this Problem?
I imagine you want to update the colours/text of them each iteration.
You don't need to create a new View each time you want to modify it. Set up your layout, get the views and then pass those views into your loop.
LinearLayout layout = new LinearLayout(this);
EditText et = new EditText(this);
TextView tv = new TextView(this);
layout.addView(et);
layout.addView(tv);
setContentView(layout);
et.setHint("Enter Command");
tv.setText(dataStringTot);
startLoop(et, tv);
public void startLoop(final EditText et, final TextView tv) {
...
}
If your loop is a thread of some sort that isn't run on the main thread you might need to wrap it in a run on ui thread.
runOnUiThread(new Runnable()
{
public void run()
{
Log.v("mainActivity", "test");
}
});

Android: Adding many children to a layout in a separate thread

I have an activity with a Button and a GridLayout with many children. If I add all these children in onCreate() my activity appears on a screen with a lag:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout main = new LinearLayout(this);
main.setOrientation(LinearLayout.VERTICAL);
Button button = new Button(this);
button.setText("test");
main.addView(button);
GridLayout testGrid = new GridLayout(this);
testGrid.setColumnCount(5);
for (int i = 0; i < 100; i++)
testGrid.addView(new Button(this));
main.addView(testGrid);
setContentView(main);
}
But I want at least my Buttton to appear immediately, so I try to add the children to the grid in a thread. After experiments I came to this solution:
final GridLayout testGrid = new GridLayout(this);
testGrid.setColumnCount(5);
main.addView(testGrid);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 100; i++)
MyActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
testGrid.addView(new Button(testGrid.getContext()));
}
});
}
}).start();
}
}, 1);
But I'm not sure it's a good idea, because it looks kinda complicated and may be it won't work well on some devices. Any better suggestions?
When you have to do something like this, it is a clear indication that you do something wrong. If you really need 100 buttons in a grid, maybe you should consider using GridView instead of GridLayout and loading buttons into view via a simple adapter.

How to change background image of buttons after 4seconds in android? Not working

I have two buttons in my sample Android app. I want to select a button randomly and change its background image(to yellow) and display it for 4-seconds. After the 4-seconds now again I want to change the background image(to blue) and display it for 4-seconds. Now to repeat the process of buttons random selections and do the same with the radomly selected button as I stated above.
I have developed some code, when I test the code for indvidual button it works fine but when I run for both the buttons its not working accordingly.
Please help me, I would be very thankfull to you. You can check my code as wl....
int mainCount =0;// mainCount- could be a random number
int count_1 =0;
int count_2 =0;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.mlayout);
mainHandler = new Handler();
mHandler1 = new Handler();
mHandler2 = new Handler();
.
.
.
mainRunnable.run();
}
Runnable mainRunnable = new Runnable(){
public void run(){
mainHandler.postDelayed(new Runnable(){
public void run(){
switch(mainCount){
case 0:
runButton1.run();
mainCount++; // mainCount- could be a random number to select a button randomly
break;
case 1:
runButton2.run();
mainCount++;// mainCount- could be a random number to select a button randomly
break;
}
if(count==2)
mainCount =0;
mainHandler.postDelayed(this,4000);
}
}, 4000);
}
};
Runnable runButton1 =new Runnable(){
public void run(){
mHandler1.postDelayed(new Runnable(){
public void run(){
switch(count_1){
case 0:
button1.setBackgroundResource(R.drawable.buttonyellow);
count_1++;
break;
case 1:
button1.setBackgroundResource(R.drawable.buttonblue);
count_1++;
break;
}
if(count_1==2)
count_1 = 0;
mHandler1.postDelayed(this,4000);
}
}, 4000);
}
};
Runnable runButton2 =new Runnable(){
public void run(){
mHandler2.postDelayed(new Runnable(){
public void run(){
switch(count_2){
case 0:
button2.setBackgroundResource(R.drawable.buttonyellow);
count_2++;
break;
case 1:
button2.setBackgroundResource(R.drawable.buttonblue);
count_2++;
break;
}
if(count_2==2)
count_2 = 0;
mHandler2.postDelayed(this,4000);
}
}, 4000);
}
};
First off, you don't need multiple Handlers, one will be enough. Second, you're calling mainRunnable.run() in onCreate to run another inner runnable so this would be better suited to just being a method. Regardless, here's my take:
public class MyActivity extends Activity {
private Runnable mEndlessRunnable;
#Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.my_activity);
mEndlessRunnable = new UpdateRunnable(new Handler(), new Button[] {
(Button) findViewById(R.id.button_1),
(Button) findViewById(R.id.button_2)
});
mEndlessRunnable.run();
}
private static class UpdateRunnable extends Runnable {
private Random mRand = new Random();
private Handler mHandler;
private Button[] mButtons;
private Button mCurButton;
private int mState;
public UpdateRunnable(Handler handler, Button[] buttons) {
mHandler = handler;
mButtons = buttons;
}
public void run() {
// select a button if one is not selected
if (mCurButton == null) {
mCurButton = mButtons[mRand.nextInt(mButtons.length)];
}
// check internal state, `0` means first bg change, `1` means last
switch (mState) {
case 0:
mCurButton.setBackgroundResource(R.drawable.blue_bg);
mState = 1;
break;
case 1:
mCurButton.setBackgroundResource(R.drawable.yellow_bg);
// reset state and nullify so this continues endlessly
mState = 0;
mCurButton = null;
break;
}
mHandler.postDelayed(this, 4000);
}
}
}
I haven't tested the above, but I'd use the above as a reference. Enjoy

android can't close dialog when run socket

I have some problem. Dialog.dismiss() does not work.
I want to input ip, username, password to login WinServer 2003. When I clicked Submit button, the dialog can't be closed. To be noted, my Thread-socket able to retrieve messages from Server and send messages back to Server. The Dialog can only be closed When the Thread-socket got error.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jiemian);
netInit();
JieMianActivity.jiemian = this;
LayoutInflater factory = LayoutInflater.from(JieMianActivity.this);
View view = factory.inflate(R.layout.login, null);
dialog02 = new AlertDialog.Builder(JieMianActivity.this)
.setIcon(android.R.drawable.btn_star)
.setTitle("login")
.setView(view)
.setPositiveButton("submit", onclickButton)
.setNegativeButton("cancel", onclickButton).create();
dialog02.show();
}
private OnClickListener onclickButton = new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.v("which", which+"");
switch(which){
case Dialog.BUTTON_POSITIVE:
dialog.dismiss();//doesn't work , cann't close dialog.
EditText ip = (EditText) findViewById(R.id.ip);
EditText username = (EditText) findViewById(R.id.username);
EditText password = (EditText) findViewById(R.id.password);
new Connect(JieMianActivity.jiemian).run();//do some socket thing
break;
case Dialog.BUTTON_NEGATIVE:
dialog.dismiss();
JieMianActivity.jiemian.finish();
break;
}
}
};
This is my Thread:
class Connect extends Thread{
private JieMianActivity jiemain;
public Connect(JieMianActivity jiemian){
this.jiemain = jiemian;
}
public void run(){
//Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);
try {
Display display = getWindowManager().getDefaultDisplay();
InputStream is = getResources().getAssets().open(
connect2RDP.mapFile);
sfv = (SurfaceView) findViewById(R.id.surfaceView);
sfh = sfv.getHolder();
sfh.addCallback(JieMianActivity.jiemian);
if (conn.connect("192.168.10.134", "Adminstrator", "123",
display.getWidth(), display.getHeight(), 3389, is)) {
Log.v("login", "success");
//dialog02.dismiss();
Log.v("login", "ok");
canvas = new MyCanvas();
canvas.setRop(new RasterOp());
canvas.setHeight(Options.height);
canvas.setWidth(Options.width);
canvas.setRight(Options.width - 1);
canvas.setBottom(Options.height - 1);
canvas.setBackstore(new WrappedImage(Options.width,
Options.height, JieMianActivity.jiemian));
canvas.setJiemian(JieMianActivity.jiemian);
canvas.setSurView(sfv);
canvas.setSurHolder(sfh);
conn.doconnect(JieMianActivity.jiemian);// 启动RDP
// init();
}
} catch (OrderException e) {
} catch (Exception e) {
}
}
};
You need to change your code to start a Thread, You need to call the method start() - that will execute the run() method written in that Thread.
So,
Invoke Connect.start() instead of Connect.run() inside your onClick handler.
I think you should close your alert dialog in UI thread else it wont work. You can do this in two ways : 1. Use message handler 2. Use RunOnUiThread. Sample for your reference :
1.
messageHandler.sendEmptyMessageDelayed(unique_id, 500);
private Handler messageHandler = new Handler()
{
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case unique_id:
// do here
break;
}
}
};
2.
Runnable hide_ui = new Runnable() {
#Override
public void run() {
// do here
}
};
runOnUiThread(hide_ui);

Adding a LeadBolt App Ad - how to add a Runnable

The doc says I should add something like this to my code:
// create a new layout
LinearLayout layout = new LinearLayout(this);
/*
Add any elements to your view
*/
// make the view visible
this.setContentView(layout);
final Activity act = this;
// now add the banner or overlay to the app
layout.post(new Runnable() { //what about this line?
public void run() {
myController = new AdController(act, MY_LB_SECTION_ID);
myController.loadAd();
}
});
My layout is in xml and I have already defined setContentView(R.layout.config); I mean the layout.post(new Runnable() { line. How should I modify the code?
For anyone who is interested I have found the obvious solution:
RelativeLayout rellaymain = (RelativeLayout)findViewById(R.id.rellaymain);
final Activity act = this;
rellaymain.post(new Runnable() {
public void run() {
myController = new AdController(act, MY_LB_SECTION_ID2);
myController.setAsynchTask(true);
myController.loadAd();
}
//});
});
rellaymain is the layout of the .xml file.

Categories

Resources