I am creating a GenericListCellRenderer with Textfield, i need to edit the textfield and replace the values in it, but i didn't get any focus when clicking the Textfield. The code i tried was as follows.
public Container createGenericRendererContainer() {
Container c = new Container(new BoxLayout(BoxLayout.X_AXIS));
c.setUIID("Container");
Label name = new Label();
name.setFocusable(true);
name.setName("Name");
c.addComponent(name);
TextField rollNo = new TextField();
rollNo.setFocusable(true);
rollNo.setUIID("TextField");
rollNo.setName("RollNo");
rollNo.setEditable(true);
rollNo.setEnableInputScroll(true);
rollNo.setEnabled(true);
c.addComponent(rollNo);
return c;
}
Henceforth, I need to get the action listener , that after i edited and press enter the values need to be changed in the database..
ListRenderer are stateless they are only used to display a list item on the list, if you need a Statefull Component don't use a List, use a box layout y Container instead.
Read this for more info - http://www.codenameone.com/blog/deeper-in-the-renderer
Related
I have to add some dynamic view based on server response and some of them are Edittext
viewmodel.needs.observe(viewLifecycleOwner, Observer {
it.data?.let {
val set = ConstraintSet()
//adding first edittext price and label
if(it.price.price1Requierd==1) {
val lbl_price1=AppCompatTextView(requireContext())
lbl_price1.id=View.generateViewId()
lbl_price1.setText(it.price.price1Title)
lbl_price1.setTypeface(typeface)
cl_price.addView(lbl_price1,ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT,ConstraintLayout.LayoutParams.WRAP_CONTENT))
set.clone(cl_price)
set.connect(lbl_price1.id,ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP)
set.connect(lbl_price1.id,ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT)
set.applyTo(cl_price)
et_price1 = AppCompatEditText(requireContext());
et_price1.id=View.generateViewId()
et_price1.setHint(it.price.price1Title)
et_price1.inputType=InputType.TYPE_CLASS_NUMBER + InputType.TYPE_NUMBER_FLAG_SIGNED
et_price1.setTypeface(typeface)
et_price1.maxLines=1
et_price1.setBackgroundResource(R.drawable.bg_select)
cl_price.addView(et_price1,ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,ConstraintLayout.LayoutParams.WRAP_CONTENT))
set.clone(cl_price)
set.connect(et_price1.id,ConstraintSet.TOP,lbl_price1.id,ConstraintSet.BOTTOM)
set.applyTo(cl_price)
}
//adding second edittext price and label
if (it.price.price2Requierd==1) {
val lbl_price2=AppCompatTextView(requireContext())
lbl_price2.id=View.generateViewId()
lbl_price2.setText(it.price.price2Title)
lbl_price2.setTypeface(typeface)
cl_price.addView(lbl_price2,ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT,ConstraintLayout.LayoutParams.WRAP_CONTENT))
set.clone(cl_price)
set.connect(lbl_price2.id,ConstraintSet.TOP,et_price1.id,ConstraintSet.BOTTOM,top_margin)
set.connect(lbl_price2.id,ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT)
set.applyTo(cl_price)
et_price2 = AppCompatEditText(requireContext());
et_price2.id=View.generateViewId()
et_price2.setHint(it.price.price2Title)
et_price2.inputType=InputType.TYPE_CLASS_NUMBER + InputType.TYPE_NUMBER_FLAG_SIGNED
et_price2.setTypeface(typeface)
et_price2.maxLines=1
et_price2.setBackgroundResource(R.drawable.bg_select)
cl_price.addView(et_price2,ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,ConstraintLayout.LayoutParams.WRAP_CONTENT))
set.clone(cl_price)
set.connect(et_price2.id,ConstraintSet.TOP,lbl_price2.id,ConstraintSet.BOTTOM)
set.applyTo(cl_price)
}
}?: run {
it.message.shortToast(requireContext())
}
})
the Edittext are Added correctly as i want but the problem is when fragment is recreated for example on orientation change or if another fragment is replaced the text of edittexts are lossing actuly the views are recreating . so how can i keep the state of edittext or any other dynamic added view like checkbox or .. tanx for your help
Try set an unique id for the dynamically created TextView.
textView.setId(View.generateViewId());
Link:
EditText not automatically saved on screen orientation change
This is driving me a little mad since I know this should be very simple but I am not getting the desired affect.
I have the following arraylist
private List<String> tagStringArray = new ArrayList<>();
Then later I have a method that creates dynamic buttons, based on ID values pulled across from my Retrofit instance.
In my method, I have a count to help me set the title of the button but I also add the values of count to an ArrayList for use in another method.
I have taken a snip of relevant information from the method mentioned.
count = 1;
if (!questionNumber.equals("") && !questionNumber.equals(null)) {
for (final Object value : list) {
try {
/*Dynamically create new Button which includes the question number
*/
final AppCompatButton btn_question = new AppCompatButton(getActivity());
/*LayoutParams (int width, int height,float weight)
As LayoutParams is defaulted in px, I have called a method called dpToPX to make sure
the dynamically added EditText is the same size on all devices.
*/
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dpToPx(280), dpToPx(45), 1);
btn_question.setBackgroundColor(Color.parseColor("#3B5998"));
btn_question.setTextColor(Color.WHITE);
btn_question.setText("Question "+count);
//set the Tag based on its position in the XML
tagStringArray.add(String.valueOf((count)));
count++;
If a user clicks on say Question 1 Button, I want my fragment to say Question 1, so to try and achieve that, I have tried doing the following:
String tags = String.valueOf(tagStringArray);
tags = tags.substring(1, tags.length() -1);
String[] currentTag = tags.split(",");
if (currentTag[0].contains("1")) {
tv_setQuestions_edit.setText("Question 1");
}else if(currentTag[1].contains("2")) {
tv_setQuestions_edit.setText("Question 2");
}
But this will always set the title to Question 1 and I am not sure what is going wrong.......
If I use the following toast Toast.makeText(getActivity(), Arrays.toString(currentTag), Toast.LENGTH_LONG).show(); it shows [1,2] so I know they are being added ok.
I did look into using tags by doing:
public static int KEY_COUNT=0; public static int KEY_VALUE=1;
btn_question.setTag(KEY_VALUE,value);
btn_question.setTag(KEY_COUNT,count);
But for some reason, when I add more than one tag (as I need a minimum of 2), my dynamic button is missing from the layout. But for some reason when only 1 tag - like this btn_question.setTag(value); is used, it shows up fine (I have a feeling its some issue with my fragment). Therefore I am trying to think of a workaround in the meantime.
Any help or guidance would be really appreciated.
It's because
currentTag[0].contains("1")
is always true. The first item of currentTag always contains "1".
Instead of doing this, why don't you just do String titleForFragment = myButton.getText() in the onClick method for the button? That way, you can set the same onClickListener on all the buttons, and it will reduce the amount of code you need to write.
I am trying to update the background color of a Label inside a TableViewRow. I am using a View/Controller for the rows, creating them in code and appending them as an array to the TableView. Using onClick of the TableViewRow and Label.setBackgroundColor() inside the TableViewRow controller.
ExampleRow.xml
<TableViewRow id="exampleRow" class="exampleClass" onClick="exampleClick">
<Label id="exampleLabel" text="test" />
</TableViewRow>
ExampleRow.js
var test = 1;
function exampleClick(e) {
if(test == 1) {
$.exampleLabel.setBackgroundColor('#0f0');
test = 0;
} else {
$.exampleLabel.setBackgroundColor('#fff');
test = 1;
}
}
ExamplePage.xml
<TableView id="exampleTable" />
ExamplePage.js
var tableViewRows = [];
for(var i = 0; i < 5; i++) {
tableViewRows.push(
Alloy.createController('exampleRow', {}).getView()
);
}
$.exampleTable.setData(tableViewRows);
The problem is this does not work on the first page as soon as the app loads. If I scroll the TableViewRows outside of the screen and back in, the background color change works. If an alert box is popped up the background change works. But after first app load, the background color will not change. It also works if we use appendRow for each row, but this is substantially slower.
appendRow fix example:
for(var i = 0; i < 5; i++) {
$.exampleTable.appendRow(
Alloy.createController('exampleRow', {}).getView()
);
}
appending the rows individually sometimes fixes the bug (not every row), but for our list takes 5-8 seconds to display the table, rather than <1second using setData*
Example of the real app not working:
Example of the real app working:
This occurs after having an alert box displayed or scrolling the rows out and back in to the screen, or using appendRow for each row
Methods I have attempted to fix (did not fix):
using animations
removing the label then recreating and adding a new label in code
removing class from the TableViewRow
I am using Titanium SDK 5.0.2.GA and compiling on android 5.1.1.
Try to use click event of tableView instead of tableViewRow :
<TableView onClick="yourTableViewClickEvent"></TableView>
and then define what logic will be executed inside this function callback :
function yourTableViewClickEvent(e){
// access selected row
var currentSelectedRow = e.row;
// current selected Label we assume here that the row contain a label as first child (exactly what you have in your row definition
var currentLabel = currentSelectedRow.children[0]
// change label background color
currentSelectedRow.backgroundColor = "#0f0"
// You can even (i know it is no good to do that :)) test if the color is white or #0f0 like so
if(currentSelectedRow.backgroundColor == "#fff")
currentSelectedRow.backgroundColor = "#0f0"
else
currentSelectedRow.backgroundColor = "#fff"
}
I'm working on App which get the data from GCM , After this I display the data in the listview and when get new data from GCM , I add these new data to the listview and I used this code
public void updateListView2(List<FeedItem> newItems) {
for(FeedItem item : newItems)
{
//Toast.makeText(this, "Title : "+item.getTitle(), Toast.LENGTH_LONG).show();
// this to add the new items at the top of the list
listAdapter.insert(item, 0);
}
// to retain the position of the listview after updated
int lastViewIndex = listView.getFirstVisiblePosition();
View view = listView.getChildAt(0);
int top = (view == null) ? 0 : view.getTop() ;
listView.setSelectionFromTop(lastViewIndex, top);
listAdapter.notifyDataSetChanged();
//this to add the button programitcally like "New Stories"
Button updateBt = new Button(this);
updateBt.setText("Updated");
feedLayout.addView(updateBt);
}
but when I tried to add the button like this "New Stories" I failed , Nothing is viewed !! so can anyone Help Me .
I would play with visibility (VISIBLE && GONE). When you get info you don't have to add the button but make it visible and with visibility GONE after clicking it (or whatever the event you want).
This may make you easier to work with hierarchies of views because you define the button in your xml layout (with visibility gone by default, at the top or in the position you need it) and change its properties dinnamically.
The best way to do is add that button and place it wherever you want in your xml layout file and set
android:visibility="gone"
or
android:visibility="invisible"
when you need the button to display, display it from java code like this
myButton.setVisibility(View.VISIBLE);
follow this, you'll get no issues.
I am creating dynamic layout in my code. My UI has multiple rows which are dynamically created at runtime. Each row consists of single edit text. I have created single edit text object and used this object to add in multiple rows.
Lets assume that there are 5 rows so there are 5 edit texts. User can enter/delete numbers in any of the edittext. Depending on what user enters in respective edittexts, I want to update the label.The label should contain addition of all edittext values.
I am calling following function on edit text afterTextChanged callback method.
private void refreshTotalNumberOfDays(Editable editable){
if(!(editable.length()==0)){
totalDays = Integer.parseInt(editable.toString());
}
finalTotalDays =totalDays+finalTotalDays;
ftotalNumberOfDays.setText(String.valueOf(finalTotalDays));
}
But its not adding values correctly.
You need to change to this:
totalDays = Integer.parseInt(editable.getText().toString());
It should give you the proper integer value.
To total all of them, keep an array of all the editTexts.
Make the array when you create the Activity
ArrayList<EditText> editTextArrayList = new ArrayList<EditText>();
editTextArrayList.add(editText1);
editTextArrayList.add(editText2);
...
Then on your callback Method, total them all up:
int total = 0;
for (EditText editText:editTextArrayList) {
total += Integer.parseInt(editText.getText().toString());
}