I'm making a random word generator and I'm having problems getting the input from the generated editText in Kotlin. I have found a few solutions in java and I can see how they work but I'm having trouble putting it into Kotlin.
I've set it up the so the EditTexts are generated by a while loop and the Id is stored in an array call "arraylist". I then wanted to use the Id in the array to obtain the "text" from each editText and put them into the "Strings" variable. I think in java you'd use "string[i]" so the variable becomes string1, string2 etc. I can't get this to work. I've tried printing the array and its blank so I don't think I'm getting the id correctly.
There are a few logic issues with code such as there already being an input that I'm using for formatting and arrays starting at 0 and such that I'll sort out later.
Thanks
Jake
class WordList : AppCompatActivity() {
#RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_word_list)
//Get Linear layout as variable
val linearLayout = findViewById(R.id.InfoLayout) as LinearLayout
val Test = findViewById(R.id.WordsInput) as EditText
val RandomiseButton = findViewById<Button>(R.id.RandomiseInputs) as Button
var Value = "Hello" as String
var editText = EditText (this)
var List = arrayListOf<String>()
var arraylist = ArrayList<Int>()
val strings = ArrayList<String>()
//Get Inputs from Previous page
var Choice = intent.getIntExtra("Amount", 0)
/*To Do
Get Inputs From Created Inputs
Randomise
Print output
*/
//Add new input
if (Choice >= 2) {
//Create Var for Edit
var Number = 2
//While loop to create multiple EditText fields
while (Number <= Choice) {
editText = EditText (this)
editText.hint = "Input " + Number
editText.setId(Number)
//Use Appearance To change things you can't set using style.xml
editText.setTextAppearance(R.style.TextHintFont)
editText.setTextColor(Color.parseColor("#E321C2"))
editText.setHintTextColor(Color.parseColor("#E321C2"))
editText.setEms(10)
//Set Edit
linearLayout.addView(editText)
arraylist.add(editText.id.toInt())
Number++
}
}
RandomiseButton.setOnClickListener {
var Random = (0..Choice).random()
var i = 0
while (i <= arraylist.size) {
strings.add(arraylist.get(i).text.toString())
i++
}
var OutputW = strings.get(Random).toString()
//Value = editText.text.toString()
var intent = Intent (this#WordList,WordsOutput::class.java)
intent.putExtra("RandomOut",OutputW)
startActivity(intent)
}
}
}
So I just worked it out
RandomiseButton.setOnClickListener {
var Random = (0..Choice).random()
var OutputW = linearLayout.getChildAt(Random) as EditText
var another = OutputW.text.toString()
var intent = Intent (this#WordList,WordsOutput::class.java)
intent.putExtra("RandomOut",another)
startActivity(intent)
}
I used the getChildAt to just randomly select a field.
more info here
https://www.i-programmer.info/programming/android/11415-android-programming-in-kotlin-layouts-and-autonaming-components.html?start=1
Only took me 3 days hahaha
Related
I'm using AS3 / AIR 3.2 for Android.
I'm having a trouble about passing my variable data to another frame. I read some forums about this but I'm only new this so I don't have yet any idea.
I have an input text and button in my frame 1 where the user will input a name then the data entered will be save. (I used SharedObject) but all the data inputted will appear on frame 2.
While my frame 2 is a dynamic text where all the data will appear.
This is the code for my frame 1
import flash.net.SharedObject;
var myName:String;
myResult.text = "";
var mySO:SharedObject = SharedObject.getLocal("test");
if (mySO1.data.myName != null){
myResult.text = mySO1.data.myName;
}
else {
myResult.text = "No Name";
}
submit_btn.addEventListener(MouseEvent.CLICK, gotomyNextFrame);
function gotomyNextFrame(event:MouseEvent):void
{
nextFrame();
myName = myInputName.text;
trace(myName);
myResult.text = myName;
mySO.data.myResult = myInputName.text;
mySO.flush();
trace(mySO.data.myResult);
}
Error: Error #1009: Cannot access a property or method of a null object reference. I think this is because I'm wrong in passing of data into frame.
Attempt: I tried show the output on the same frame and I didn't encounter any error.
Your SharedObject var is mySO and not mySO1, and to share data between frames, you can use a variable like this :
frame 1 :
...
var shared_data:String = txt_input.text
nextFrame()
...
frame 2 :
// get shared_data and use it as you like
another_input.text = shared_data
shared_object.data.current_name = shared_data
...
Edit :
/* frame 01 */
// shared_data should be declared here to be a global var not inside a function
var shared_data:String
submit_btn.addEventListener(MouseEvent.CLICK, gotomyNextFrame)
function gotomyNextFrame(event:MouseEvent):void {
// here you should just assign a value to shared_data var
shared_data = yourName.text
nextFrame()
}
/* frame 2 */
stop()
import flash.net.SharedObject
// if you redefine shared_data var here you will lost it's value and you will get a null value
// var shared_data:String
var mySO:SharedObject = SharedObject.getLocal("test1")
myResult.text = shared_data
// here your SharedObject object is named mySO and not SharedObject
//SharedObject.data.mySO = shared_data
mySO.data.yourName = shared_data
Is there any way to predefine a value for strings in order not to have the error when any of the fields are empty?
All porcentagem 1, 2 and 3 are optional, so it's not the case to ask the user to input some data, but predefine values in order not to have the values. Beginner question.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cpc_inicial = (EditText) findViewById(R.id.cpc_inicial);
porcentagem1 = (EditText) findViewById(R.id.porcentagem1);
porcentagem2 = (EditText) findViewById(R.id.porcentagem2);
porcentagem3 = (EditText) findViewById(R.id.porcentagem3);
cpc_final = (TextView) findViewById(R.id.cpc_final);
botao1 = (Button) findViewById(R.id.botao1);
cpc_inicial.setInputType(InputType.TYPE_CLASS_NUMBER);
porcentagem1.setInputType(InputType.TYPE_CLASS_NUMBER);
porcentagem2.setInputType(InputType.TYPE_CLASS_NUMBER);
porcentagem3.setInputType(InputType.TYPE_CLASS_NUMBER);
botao1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(porcentagem3 != null ) {
float cpc = Float.parseFloat(cpc_inicial.getText().toString());
float v1 = Float.parseFloat(porcentagem1.getText().toString());
float v2 = Float.parseFloat(porcentagem2.getText().toString());
float v3 = Float.parseFloat(porcentagem3.getText().toString());
TextView cpcfinal = cpc_final;
if(cpc > 0.0 && v1 != 0.0 && v2 != 0.0 && v3 != 0.0 )
{
soma = (cpc*v1/100)+cpc;
soma = soma*(v2/100)+soma;
soma = soma*(v3/100)+soma;
String sum = Float.toString(soma);
cpcfinal.setText(sum);
}
} else
{
TextView cpcfinal = cpc_final;
soma = 0;
cpcfinal.setText("ops!"); }
}
});
}
Thanks
Every time a form is submitted, you should check whether each field has a proper value. For example, if you want to check weather an optional field has a value or not, you should do something like this:
String optionalText = optionalFieldName.getText().toString();
if (optionalText.equals("some expected value")) {
//Do something with the value here.
}
Of course, you would need to do something similar for every optional field, and really should also do the inverse for fields that are not option to be safe, and perhaps warn the user that the field is required, for example:
String text = fieldName.getText().toString();
if (text.equals("")) {
//field is empty, so warn the user that it is required.
}
If the value you are looking for should be numerical in nature, then you should do something like this:
String text = field.getText().toString();
if (!text.equals("")) {
//Field has at least some text in it.
try {
float val = Float.parseFloat(text);
}catch (NumberFormatException ex) {
//Enterered text was not a float value, so you should do something
// here to let the user know that their input was invalid and what you expect
}
//Do something with the value
}
Either add the values to your xml layout using the android:text="..." attribute or use TextUtils.isEmpty(...) to detect if the string is empty and assign a default value yourself.
I have an application that has 2 screens. The first screen has a ListView of movies with a row consisting of 3 Elements: Title, Date and Gross declared in strings.xml. The user has the option of adding a movie by clicking the menu button, which sends him to another screen. The second screen has 3 Edit texts that correspond to Title Date and Gross, which is alphabetically sorted straight away when it returns to screen 1.
Similarly, the user can also Edit/Delete entries by long clicking a row thatbrings up a context menu. The Edit function works like this:
a.) User long clicks Titanic and chooses Edit
b.) Row gets deleted, and user is brought to screen 2
c.) Edit texts are populated with the initial data from the deleted Row
d.) When user edits data, new movie is added at the bottom of the ListView.
The problem arises when the user deletes this new movie at the bottom of the ListView. Logcat gives a
java.lang.IndexOutOfBoundsException: Invalid index 50, size is 50
Here is my code (Take note I am using Perst to persist data, but I don;t think that won't really matter with my problem):
case R.id.contextedit:
Lab9_082588FetchDetails row = (Lab9_082588FetchDetails) getListView()
.getItemAtPosition(info.position);
Intent editData = new Intent(MovieList.this, Lab9_082588Edit.class);
String startTitle = row.getTitle();
String startGross = row.getGross();
String startDate = row.getDate();
editData.putExtra(Lab9_082588Edit.TITLE_STRING, startTitle);
editData.putExtra(Lab9_082588Edit.GROSS_STRING, startGross);
editData.putExtra(Lab9_082588Edit.DATE_STRING, startDate);
startActivityForResult(editData, MovieList.EDIT_MOVIE);
int posEdit = info.position;
String editTitle = results.get(info.position).getTitle();
results.remove(posEdit);
adapter.notifyDataSetChanged();
//Perst
Index<Lab9_082588FetchDetails> rootEdit = (Index<Lab9_082588FetchDetails>) db
.getRoot();
rootEdit.remove(editTitle, results.get((int) info.id));
db.setRoot(rootEdit);
return true;
Edit Class:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection using item.getItemId()
switch (item.getItemId()) {
case R.id.edit:
next();
break;
}
return true;
}
private void next() {
// TODO Auto-generated method stub
EditText movieTitle = (EditText) findViewById(R.id.etTitle);
EditText movieGross = (EditText) findViewById(R.id.etGross);
EditText movieDate = (EditText) findViewById(R.id.etDate);
String title = movieTitle.getText().toString();
String gross = movieGross.getText().toString();
String date = movieDate.getText().toString();
if ((title.length() > 0) && (gross.length() > 0)
&& (date.length() == 4)) {
Intent hobby = getIntent();
hobby.putExtra(Lab9_082588Edit.TITLE_STRING, title);
hobby.putExtra(Lab9_082588Edit.GROSS_STRING, gross);
hobby.putExtra(Lab9_082588Edit.DATE_STRING, date);
setResult(RESULT_OK, hobby);
finish();
}
}
Delete function:
int posDelete = info.position;
String deleteTitle = results.get(
info.position).getTitle();
results.remove(posDelete);
adapter.notifyDataSetChanged();
Index<Lab9_082588FetchDetails> rootDelete = (Index<Lab9_082588FetchDetails>) db
.getRoot();
rootDelete.remove(deleteTitle,
results.get(info.position));
db.setRoot(rootDelete); //Perst
return;
OnActivityResult (Edit):
case EDIT_MOVIE:
Lab9_082588FetchDetails edittedMovie = new Lab9_082588FetchDetails();
NumberFormat formatterEdit = new DecimalFormat("###,###,###");
edittedMovie.setTitle(data
.getStringExtra(Lab9_082588Add.TITLE_STRING));
edittedMovie.setGross("$"
+ formatterEdit.format(Double.parseDouble(data
.getStringExtra(Lab9_082588Add.GROSS_STRING))));
edittedMovie.setDate(data
.getStringExtra(Lab9_082588Add.DATE_STRING));
results.add(edittedMovie);
adapter.notifyDataSetChanged();
Populating the Listview:
for (int i = 0; i < items.size(); i++) {
Lab9_082588FetchDetails sr = new Lab9_082588FetchDetails();
sr.setTitle(items.get(i).getTitle());
sr.setGross(items.get(i).getGross());
sr.setDate(items.get(i).getDate());
results.add(sr);
Collections.sort(results, ignoreCaseStart);
}
How do I remedy this?
This problem occurs because in your delete function, you first remove the element from the results collection("results.remove(posDelete);"), and then, a few lines later, you call "results.get(info.position)" to fetch a parameter for the rootDelete.remove call, but which is already removed.
If the element is the last element of your collection, let's say the 50th element, the value for "info.position" is 50. You remove one element, so the number of elements is now 49. In the rootDelete.remove line you call results.get(50), which produces the error.
I've created a timetable app, which allows the user to enter data and then view it.However if the user enters an entry, on a day and time where there already is one, my emulator crashes(forces a close).
Basically I'm pulling back data to a linear layout- which contains 10 TextViews, each representing the times 9-15.
Here's the code:
public void addMondayGrid() {
// TODO Auto-generated method stub
for (int index = 0; index < info.mon.size(); index++) {
// int entryId = info.monIds.get(index);
int time = info.monTimes.get(index);
int id = info.monIds.get(index);
int duration = info.monDuration.get(index);
String dayOfWeek = "mon";
timeId = getResources().getIdentifier("mon" + time, "id",
getPackageName());
if (duration == 1) {
SpannableString text = new SpannableString(info.mon.get(index));
setEntryColour(text);
final TextView textV = (TextView) findViewById(timeId);
textV.setTextSize(10);
textV.setText(text, BufferType.SPANNABLE);
textV.setId(id);
deleteGridEntry(textV);
} else {
longerDuration(time, index, id, info.mon, dayOfWeek);
}
}
}
The thing is is works fine as long as there isn't two entries for the same day and time, eg. monday at 9 oclock.
Anyone have any ideas?I'm quite new to this and any help would be much appreciated!
I have to reference the id this way as there are too many ids to reference any other way,is there not a simple way to overwrite the old textView with new data pulled back from the database? I want the id to be the same one as that is the textView I want to deal with, but it just keeps crashing, is it something to do with instances?
change:
final TextView textV = (TextView) findViewById(timeId);
to:
final TextView textV = (TextView) findViewById(R.id.timeId);
I have an odd problem, (see shorter version at the bottom first please)
When my activity starts for the first time, the listview shows the dataset fine. The adapter is a custom adapter which shows 2 rows of text and an image. I call an asynctask upon a click event to the listview, the dataset updates in accordance with whatever was clicked on in the listview - more specifically the arrays which are associated with the adapter become rewritten with the parsings of some xml, and then notifyachapterdatasetchanged method is called to update the listview in the onPostExecute function. However I always get NullPointerException when I am iterating through some xml (which is very well formed and validates). ALso its worth mentioing that the algorithm that parses the desired values is good, because as mentioned above, if i write to just 1 element of the array then I dont get the error I just get the last node value so its looping in the correct places. i.e If I simple try to copy the current node value I am parsing during the loop into, say, producyTypes[0] then the last value from within the loop actually makes it to the listview as it constantly overwrites this elemet of the array
Here is my code.`
public class main extends Activity implements OnItemClickListener
{
String selectedType="";
ListView lview3;
ImageView iv;
ListViewCustomAdapter adapter;
String test = "";
List<String> ls;
String productTypes[] = {"Monitor","Components","Systems","Laptops","Flash / Usb Memory",
"Networking","Cables","Peripherals","Sound and Vision", "Software"};
String productsIncluded[] = {"Sizes (inches) 17, 19, 20",
"Motherboards, PSU, Cases, Fans/Heatsinks/Coolers, Barebones Systems, Blue-Ray/DVD. Card Readers, Controller Cards, Drive Enclosures, Sound Cards",
"Bundles, Switches and Hubs, Print Servers, Accessories/Modules",
"Cables for: Drives, Networking, HDMI/Monitor, Audio/Video, USB/Firewire, Power, Miscellaneous",
"Mice, Connectors, Bluetooth Devices",
"Mp3/Mp4 Solar Panel",
"Anti-Virus, Internet Security, Operating Systems, Office,,
"",
""};
private static int images[] = {R.drawable.monitor, R.drawable.components, R.drawable.systems,
R.drawable.laptops, R.drawable.flashusb, R.drawable.networking, R.drawable.cables, R.drawable.
peripherals, R.drawable.soundandvision, R.drawable.software};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv = (ImageView)findViewById(R.id.ImageView01);
iv.setImageResource(R.drawable.logo);
iv.setVisibility(View.VISIBLE);
lview3 = (ListView) findViewById(R.id.listView3);
adapter = new ListViewCustomAdapter(main.this, productTypes, productsIncluded, images);
lview3.setAdapter(adapter);
lview3.setOnItemClickListener(main.this);
}
#Override
public void onItemClick(AdapterView arg0, View arg1, int position, long id) {
selectedType = "";
if(position == 0)
{
selectedType= "Monitors";
}
if(position == 1)
{
selectedType= "Hard Drives";
}
Toast.makeText(this, Integer.toString(position), Toast.LENGTH_SHORT).show();
new async().execute();
/*
Intent intent = new Intent(getApplicationContext(),activitywo.class);
Bundle bundle =new Bundle();
bundle.putString("selectedType",selectedType);
intent.putExtras(bundle);
startActivity(intent);
//Toast.makeText(this, "Title => "+productTypes[position]+" \n Description => "+productsIncluded[position], Toast.LENGTH_SHORT).show();
*/
}
private class async extends AsyncTask<String, Void, Void> {
// UI Thread
protected void onPreExecute() {
}
// automatically done on worker thread (separate from UI thread)
protected Void doInBackground(final String... args) {
try{
Resources res = getResources();
InputStream in;
in = res.openRawResource(R.raw.core);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(in);
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("entry");
count=0;
for(int i =0;i<items.getLength();i++){
Node item = items.item(i);
NodeList properties = item.getChildNodes();
//productsDefinedByTypeArray = new String[properties.getLength()];
for(int j = 0;j<properties.getLength();j++){
Node property = properties.item(j);
String name = property.getNodeName();
if(name.equalsIgnoreCase("g:product_type")){//everytime we hit g:product_type grab the value
String strText = property.getFirstChild().getNodeValue();
if(strText.contains(selectedType)){
//
for(int k = 0;k<properties.getLength();k++){
Node propertysecond = properties.item(k);
String namesecond = propertysecond.getNodeName();
if(namesecond.equalsIgnoreCase("title")){//everytime we hit title grab the value
String strTextsecond = propertysecond.getFirstChild().getNodeValue();
productTypes[0] = strTextsecond;
yo = strTextsecond;
count++;
}
}
}
}
}
}
The code crashes at the point where I am trying to copy the value of a "title" node that I parse out of my xml file into the list-String-. I am using a list-string- to show that even if you try and copy the value into the array itself (the array that is associated with the adapter), even if you comment out the notifydatasetchanged () line the program still crashes. The xml is well formed and very consistent. I know this because (aecept the fact its really small and I have read it all) ! Why can I not copy every node value into my array/list whilst the loop is in progress?
Any help is massively appreciated. Thank you.
Shorter version:
I cannot write to the List
if(strText.contains(selectedType)){
//
for(int k = 0;k<properties.getLength();k++){
property = properties.item(k);
name = property.getNodeName();
if(name.equalsIgnoreCase("title")){//everytime we hit title grab the value
String strTextsecond = property.getFirstChild().getNodeValue().toString();
ls.add(strTextsecond.toString());
//test = strTextsecond;
}
}
}
Maybe you forget initialize ls? I don't find in your code something like:
ls = new List<String>();