Not able to create buttons dynamically - android

I have an overlay on my screen which will show some buttons to control the feature. This overlay will have a dynamic list of buttons which will be created based on the number of steps. Example if steps are 3 then 3 button will get created. I have created a LinearLayout inside this buttons will get created. I have created a method which will set all the button attributes, but somehow it's giving me null pointer exception.
In onCreateView I have initialize the buttonArray.
Here is my fragment:
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mContext = getActivity();
gc = GlobalClass.getInstance(mContext);
db = DataBaseHelper.getInstance(mContext);
sectionButtons = new Button[3];
/*if(savedInstanceState!=null)
mVisible = savedInstanceState.getBoolean("visible",false);*/
manager = SharedPreferenceManager.getInstance(mContext);
//check wether to play video in cover mode or another mode
inflater.inflate(R.layout.fragment_video_side_by_side, container, false);
}
and onViewCreated() I am calling my method addSections():
// show overlay with buttons in onTouch
parentLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (!mVisible) {
overLay.setVisibility(View.VISIBLE);
addSections(3);
mVisible = true;
} else {
overLay.setVisibility(View.GONE);
mVisible = false;
}
}
return true;
}
});
Method:
public void addSections(int numOfSection){
if(numOfSection==0)
return;
else {
for (int i = 0; i < numOfSection; i++) {
//set the properties for button
sectionButtons[i].setLayoutParams(new LinearLayout.LayoutParams(50, 50));
sectionButtons[i].setBackgroundResource(R.drawable.round_button);
sectionButtons[i].setText("Section "+i+"");
sectionButtons[i].setId(i);
//add button to the layout
mSectionLayout.addView(sectionButtons[i]);
}
}
}
mSectionLayout is my parent LinearLayout. While debugging I found my sectionButtons is not showing null but while setting the attributes it's throwing nullPointer exception.

Create Dynamic Buttons and attach with the Layout
You can easily create the dynamic button by the following way:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
TextView textView = new TextView(this);
textView.setText("Text View ");
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
layout.addView(textView, p);
Button buttonView = new Button(this);
buttonView.setText("Button");
buttonView.setOnClickListener(mThisButtonListener);
layout.addView(buttonView, p);
}
private OnClickListener mThisButtonListener = new OnClickListener() {
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Hello !",
Toast.LENGTH_LONG).show();
}
};
}
Using this code, you easily generate a list of buttons on the layout.
Happy coding

Related

Transition / Animation (onTouchListener)

So here is the code of simple transitioning,from top_left to bottom_right, I dont understand why I have to return false for onTouch() to work properly,
1.If I set return true, one a single touch , it sets counter from 0 to 3 , or simply adds 2 or 3 to the counter and most of the time remains at its current position.
2.If I set return false, the program runs fine and does what is written ,i.e counter++;
public class MainActivity extends AppCompatActivity {
Button b;
TextView tv;
public static int counter_button=0,counter=0;
RelativeLayout.LayoutParams old_rules;
RelativeLayout rl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b= (Button) findViewById(R.id.b1);
tv= (TextView) findViewById(R.id.tv1);
rl= (RelativeLayout) findViewById(R.id.rl);
old_rules= (RelativeLayout.LayoutParams) b.getLayoutParams();
rl.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
my_changes_touch();
return false;
}
});
}
public void my_changes_touch(){
RelativeLayout.LayoutParams rules= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
if(counter%2==0) {
counter++;
tv.setText(" "+counter);
rules.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
rules.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
b.setLayoutParams(rules);
rules.height=400;
rules.width=400;
b.setLayoutParams(rules);
getContentTransitionManager().beginDelayedTransition(rl);
} else {
counter++;
tv.setText(" "+counter);
b.setLayoutParams(old_rules);
getContentTransitionManager().beginDelayedTransition(rl);
}
}
}
The return value determines the event is consumed by the view or not.
So true means that you are interested in other events also.
If you return false then the touch event will be passed to the next View further up in the view hierarchy and you will not receive any further calls.
Please check this answer
https://stackoverflow.com/a/3756619/2783541

Dynamically add LinearLayout into LinearLayout

I have a issue trying to dynamically add some linear layout into a linearlayout container after user have clicked on a button.
private void AddView() {
MyView myView1 = new MyView("Name");
this.mainLinearLayout.addView(myView1);
}
This code works great in activity's onCreate method but not after handling user event.
Do you have any idea why it's not working ? (I mean nothing appears on UI)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AddView(); => works great
}
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddView(); => not working
}
});
Thanks,
I think that AddView is wrong.
private void addView() {
LayoutParams lparams = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
MyView myView1 = new MyView("Name");
myView1.setLayoutParams(lparams);
this.mainLinearLayout.addView(myView1);
}

Change TextView Color pressing a button

I'm trying to create an activity entirely by java code. The goal here is to create an Activity that fills up itself by previous activity. It's a shop list activity.
The user add itens in the previous activity and when he ask to show the complete list the activity above will be generated.
The problem here is, I want to set red as the initial color of the textviews with the itens names, and when the user clicks on then, they change their color to green.
But when I click it the aplication force close with the message indexoutofbounds exception.
Could someone helps me?
public class Listdinamiccor extends Activity {
Bundle recebendoparametros;
int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listdinamiccor);
Intent parametro = getIntent();
recebendoparametros = parametro.getExtras();
int j = recebendoparametros.getInt("i");
ScrollView sv = new ScrollView(this);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
sv.addView(ll);
final TextView[] tvarray = new TextView[j];
for (i = 0; i < tvarray.length; i++) {
String chave = "chave"+i;
final TextView tv = new TextView(this);
tvarray[i] = new TextView(this);
tvarray[i].setText(""+recebendoparametros.getString(chave));
tvarray[i].setTextColor(Color.RED);
tvarray[i].setOnClickListener(new View.OnClickListener() {
int click = 0;
#Override
public void onClick(View v) {
/*if (click == 0) {
tvarray[i].setTextColor(Color.GREEN);
}
else {
tvarray[i].setTextColor(Color.RED);
}*/
AlertDialog.Builder alert = new AlertDialog.Builder(Listdinamiccor.this);
alert.setTitle("dinamico");
alert.setMessage("eu sou muito dinamico");
}
});
ll.addView(tvarray[i]);
}
this.setContentView(sv);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.listdinamiccor, menu);
return true;
}
}
When your loop has completed executing, i is now set to tvarray.length -- your onClick handler doesn't "remember" the value of i, it simply does what you tell it to, which is to setTextColor on tvarray[i], and i is now out of bounds.
One way to solve it is to do this above your setOnClickListener line:
final TextView me = tvarray[i];
And then change your onClick method to call me.setTextColor instead of tvarray[i].setTextColor.
Also, I wouldn't recommend hanging onto the int i outside of your loop - I'm assuming you moved the member to the parent class so that your current code compiled, but in general you don't want to use for loop indexes outside of the for loop (this exception is one such reason).
Try casting your View v to a TextView inside your onclick listener instead of using the instance your creating in your array like this:
tvarray[i].setOnClickListener(new View.OnClickListener() {
int click = 0;
#Override
public void onClick(View v) {
if (click == 0) {
((TextView)v).setTextColor(Color.GREEN);
}
else {
((TextView)v).setTextColor(Color.RED);
}
AlertDialog.Builder alert = new AlertDialog.Builder(Listdinamiccor.this);
alert.setTitle("dinamico");
alert.setMessage("eu sou muito dinamico");
}
});

Creating Android overlays for displaying Walk-through

This is what I've done to implement CommonsWare's answer in the following question:
How do I create a help overlay like you see in a few Android apps and ICS?
But it fails. There are no errors but nothing appears when I run (I've made sure that the isFirstTime() function below is functioning properly
#Override
public void onCreate(Bundle savedInstanceState)
{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
if(isFirstTime())
{
LayoutInflater inflater = LayoutInflater.from(this);
final FrameLayout overlayFrameLayout = new FrameLayout(this);
setContentView(overlayFrameLayout);
overlayFrameLayout.addView(inflater.inflate(R.layout.main, null));
overlayFrameLayout.addView(inflater.inflate(R.layout.overlay, null));
overlayFrameLayout.setVisibility(View.VISIBLE);
overlayFrameLayout.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
overlayFrameLayout.setVisibility(View.INVISIBLE);
overlayFrameLayout.removeViewAt(1);
return false;
}
});
}
setContentView(R.layout.main);
ctx = getApplicationContext();
I'm pretty sure that I've gone wrong when creating the FrameLayout. Appreciate the help, thanks!
You don't see anything because you call setContentView twice and the R.layout.main is being inflated and replacing your previously created and assigned overlayFrameLayout. The following code should sort it out.
#Override
protected void onCreate(Bundle savedInstanceState)
{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
if(isFirstTime()){
final LayoutInflater inflater = getLayoutInflater();
final FrameLayout frameLayout = new FrameLayout(this);
inflater.inflate(R.layout.main, frameLayout, true);
final View overlayView = inflater.inflate(R.layout.overlay, frameLayout, false);
overlayView.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
frameLayout.removeView(overlayView);
return false;
}
});
frameLayout.addView(overlayView);
setContentView(frameLayout);
}
else{
setContentView(R.layout.main);
}
}

Displaying PopUpWindow from an other Class - Android

Basically, I have two classes :
- MyActivity.java
- OtherClass.java
Overview of MyActivity.java :
Nothing really interesting in there ... except the instanciation of what is need by the otherClass.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = getApplicationContext() ;
main_activity = this ;
layout = (LinearLayout) findViewById(R.id.layout);
/*
* Do lot of stuff
*/
}
Overview of OtherClasse.java :
It has a clickable TextView. And when I make a LongClick event, I would like to display a PopUpWindow (on the UI-Thread, so MyActivity ...)
view.setOnLongClickListener( new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Log.d("TAG", "OnLongClick");
PopupWindow popup = new PopupWindow(activity.getApplicationContext());
//tried with new PopupWindow(MyActivity.context);
popup.setWindowLayoutMode(150, 150);
popup.setContentView( view );
//view corresponds to the TextView.
popup.showAtLocation(MyActivity.layout, Gravity.CENTER_HORIZONTAL, 10, 10);
return true;
}
});
The log indicate that I entered in the onLongClick() ...
But the application crash ...
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
But MyActivity.layout is a static LinearLayout, so I would be able to add view to it ...
Any suggestion on how to show PopUpWindow from onClickListener of an other Class ?
EDIT :
#Override
public boolean onLongClick(View v) {
PopupWindow popup = new PopupWindow(BlaActivity.context);
TextView tv = new TextView(BlaActivity.context);
LayoutParams para = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(para);
tv.setText("My future text ...");
popup.setContentView(tv);
popup.setWidth(400);
popup.setHeight(180);
popup.showAtLocation(tv, Gravity.CENTER_HORIZONTAL, 10, 10);
popup.update();
return true;
}
Returns a
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
Because popup.showAtLocation(tv, Gravity.CENTER_HORIZONTAL, 10, 10); Calls to public IBinder getWindowToken () on tv ... Witch doesn't have Token obviously ...
The view you refer to here
popup.setContentView( view );
could be the problem. You create a new instance of the pop up window each time but if you are using the same textview each time then that is what would be causing the IllegalStateException.
The following code is simply an activity and a second class. onLongClick creates an instnce of AnotherClass and calls showPopUp.
The constructor of AnotherClass takes in a context as a parameter, which is later used to instantiate the popup.
showPopUp takes in a view which is used as a parent for the popup.
the activity's onCreate
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b = (Button)findViewById(R.id.button1);
final RelativeLayout parent = (RelativeLayout)findViewById(R.id.layout);
b.setOnLongClickListener( new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
new AnotherClass(getApplicationContext()).showPopUp(parent);
return true;
}
});
}
a second class
To use a click/touch listener in OtherClass you can declare them as you normally would but to create a popup inside the listener you need give the context of an activity. Something like this is fine
public class AnotherClass {
Context ctx;
public AnotherClass(Context ctx){
this.ctx = ctx;
//***EXAMPLE*** wont actually be visible as its not added to a view
Button b2 = new Button(ctx);
b2.setText("show popup");
b2.setOnLongClickListener( new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
showPopUp(v);//View v can be used as the parent
return true;
}
});
}
public void showPopUp(View parent) {
PopupWindow popup = new PopupWindow(ctx);
TextView tv = new TextView(ctx);
LayoutParams para = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(para);
tv.setText("My future text ...");
popup.setContentView(tv);
popup.setWidth(400);
popup.setHeight(180);
popup.showAtLocation(parent, Gravity.CENTER_HORIZONTAL, 10, 10);
popup.update();
}
}
and the xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:background="#android:color/black" android:id="#+id/layout">
<Button android:layout_height="wrap_content"
android:layout_width="wrap_content" android:id="#+id/button1"
android:text="Button" android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" android:layout_marginLeft="51dp"
android:layout_marginTop="28dp"></Button>
</RelativeLayout>

Categories

Resources