[TUTORIAL][ANDROID] How to add touch events to RecyclerView - Android Studio

At first, it probably seems a better choice to use RecyclerViews instead of the ordinary ListViews but one of the issues that people come across is that there are no touch events implemented in RecyclerViews.
While developing Chatto (re-writing from scratch), I came up with a very logical solution for this. If you are you currently using RecyclerViews, you should be familiar with ViewHolders.
Firstly, in your model layout file for the RecyclerView (.xml file), add an id for the layout that you are using. In my layout file, I'm using a RelativeLayout.
Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:paddingBottom="5dp"
android:id="@+id/chatroomListRelativeRow">
Now let's take a look at a snippet from a custom ViewHolder class that I wrote for Chatto.
Code:
public class RoomViewHolder extends RecyclerView.ViewHolder{
private TextView mLblRoomName;
private TextView mLblRoomCounter;
private ImageView mImgRoomType;
private RelativeLayout chatroomListRelativeRow;
public String roomName;
Notice the line private RelativeLayout chatroomListRelativeRow. As you can see, I've created a RelativeLayout object.
Inside the constructor of the ViewHolder class, I've linked the object back to the RelativeLayout in the .xml file.
Code:
chatroomListRelativeRow = RelativeLayout)v.findViewById(R.id.chatroomListRelativeRow);
Now we can use this object to add the onClickListeners and other touch events.
Code:
chatroomListRelativeRow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Log.d("RVH",mLblRoomName.getText().toString());
//FragMessagesList fragMessagesList = new FragMessagesList();
roomName = mLblRoomName.getText().toString();
//go to messages
}
});
In the above code, I've attached a OnClickListener to the RelativeLayout. This means when the user clicks on any part of the layout (RecyclerView row), it will perform the specified action.
Now you can try this out for yourself.
As an addition, I've also attached a OnTouchListener to the layout. In this listener, I'm simply changing the colors when user touches the row and when the row is not touched. Now let's see how its done.
In order to obtain the original color of the layout, I've created a Drawable and called the
Code:
.getBackground()
method on the layout.
Code:
final Drawable origColor = chatroomListRelativeRow.getBackground();
Now we can use this to set the color back to the original color/background when the user is not touching on the row.
Code:
chatroomListRelativeRow.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
chatroomListRelativeRow.setBackgroundColor(Color.parseColor("#212121"));
}
else{
chatroomListRelativeRow.setBackground(origColor);
}
return false;
}
});
That's all there is to it!

Related

[Q] Update a TextView after edit a EditText

Hi all,
Some days ago I decided to make an app to help me in my job with some Maths, so I'm reading a lot and watching some classes on youtube to make it possible. I'm trying to make, basically, a calculator for some specific maths.
By a simple way, I learned how to make my EditText,TextView , and do the Math when I push one BUTTON, but in some cases, for a fast and easy result, would be better to update the "children" field, just when I edit the "parent" field, or when I leave it.
Like, if I type the number 1 in my first field, the second field that depends on it should update automatically using this reference that I just edited.
Is there possible ? If yes, recommended or it makes the app too "heavy" ? Considering that each activity would have just few maths, far from any big known app.
Thanks in advanced.
Barata
Hello,
Let's suppose you have one EditText and one TextView, with ids in your xml: myedittext1 and mytextview2. You can easily achieve that. I don't think that it will be heavy just for few maths But also if it is heavy, it can be done without making the UI thread unresponsive, using thread for the calculations.
So
Code:
final EditText et1 = (EditText) findViewById(R.id.myedittext1);
final TextView tv2 = (TextView) findViewById(R.id.mytextview2);
et1.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
//This is called AFTER the text has changed
//Now update the tv2
String textOutput = ...;
//tv2.setText(textOutput);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//This is called BEFORE the text has changed
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//This is called WHENEVER the text has changed
}
});
Button b1 = (Button) findViewById(R.id.mybutton);
b1.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//do your math calculations here (if they are heavy, start a thread here)
//Edit the et1 here
//tv2 will be edited automatically according to the afterTextChanged above
}
});
If you would like to start a thread (if your maths are heavy), to avoid UI pausing and slow response from UI, follow the below code
//Thread solution (avoid making UI "laggy")
Before onCreate inside you Activity class:
Code:
EditText et1 = null;
TextView tv2 = null;
Thread t1 = null;
MyCalc mycalc = null;
MyCalc2 mycalc2 = null;
private class MyCalc implements Runnable{
public MyCalc(){
}
@Override
public void run(){
//Do you math here
final String outputText = ...;
try{
runOnUiThread(new Runnable() {
@Override
public void run() {
//Here set et1 text
et1.setText(outputText);
//tv2 text will be updated automatically
}
});
}catch (InterruptedException e){
}
});
}
private class MyCalc2 implements Runnable{
public MyCalc2(){
}
@Override
public void run(){
//Do you math here
final String outputText = ...;
try{
runOnUiThread(new Runnable() {
@Override
public void run() {
//Here set et1 text
et1.setText(outputText);
//tv2 text will be updated automatically
}
});
}catch (InterruptedException e){
}
});
}
Inside onCreate:
Code:
et1 = (EditText) findViewById(R.id.myedittext1);
tv2 = (TextView) findViewById(R.id.mytextview2);
et1.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
//This is called AFTER the text has changed
//if you need to do calculation here also, do:
mycalc2 = new MyCalc2(); //where MyCalc2 is the same as MyCalc but with different calculations :P
t1 = new Thread(mycalc2);
t1.start();
//Set tv2 text here.
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//This is called BEFORE the text has changed
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//This is called WHENEVER the text has changed
}
});
Button b1 = (Button) findViewById(R.id.mybutton);
b1.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
mycalc = new MyCalc();
t1 = new Thread(mycalc);
t1.start();
}
});
In onDestroy:
Code:
if(t1!=null){
if(t1.isAlive()==true){
if(t1.isInterrupted()==false){
t1.interrupt();
try{
t1.join();
}catch (InterruptedException e){
}
}
}
t1= null;
}
If you still need help, feel free to ask
Really thanks for the reply @MMDeveloper, but had some problems here, I'm trying to find a Solution for almost 1hr, and nothing.. I saw some ppeople with the same problem, but couldnt use the answers I've read to solve this code.
With the first solution you gave to me, I just delete the button part, just to try make all automatic. In this first sample I have just a simple math that should convert a CV power do kW
The studio shows that to me:
addTextChangedListener - Cannot resolve symbol;
TextWatcher - Invalid method declaration, return type required;
@Override - Annotations are not allowed here;
Editable arg0 - Cannot resolve symbols, for both;
I tried to put this code in different places in my main java, but nothing. Below is my XML and then my Java, could you take a look in it please ? I guess I'm used to copy and paste some codes from some classes, and that is harming me, i really need to start all over from the java sintaxe.
The fields I've changed to be those in your code are: torque_p_cv (edit) and torque_p_cv (view)
XML:
Code:
<RelativeLayout xmlns:android="CANT SHOW LINK UNDER 10 POSTS"
xmlns:tools="CANT SHOW LINK UNDER 10 POSTS"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".Calculos001_Main">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cálc. do torque em função de P e n"
android:id="@+id/torque_titulo"
android:layout_gravity="center_horizontal"
android:textAlignment="center"
android:layout_marginTop="10dp"
android:textSize="20dp"
android:textStyle="bold|italic" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="P"
android:id="@+id/torque_tits_p" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Potência do motor"
android:id="@+id/textView"
android:layout_marginStart="10dp" />
<EditText
android:layout_width = "0dp"
android:layout_height="wrap_content"
android:id="@+id/torque_p_cv"
android:layout_weight="1"
android:inputType="number"
android:hint="Potência"
android:gravity="end"
android:layout_marginStart="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="CV"
android:id="@+id/unidade_CV"
android:textAlignment="textEnd"
android:gravity="end"
android:layout_marginStart="10dp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="xxxxx"
android:id="@+id/torque_p_kw"
android:textAlignment="textEnd"
android:gravity="end"
android:layout_marginStart="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="kW"
android:id="@+id/unidade_kW"
android:textAlignment="textEnd"
android:gravity="end"
android:layout_marginStart="10dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
and the Java:
Code:
package com.example.tbarata.calculos_001;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
public class Calculos001_Main extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculos001__main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_calculos001__main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
final EditText et1 = (EditText) findViewById(R.id.torque_p_cv);
final TextView tv2 = (TextView) findViewById(R.id.torque_p_kw);
et1.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
//This is called AFTER the text has changed
//Now update the tv2
String textOutput = "0";
//tv2.setText(textOutput);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//This is called BEFORE the text has changed
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//This is called WHENEVER the text has changed
}
});
}
Really thanks,
Barata
Hello again!!
I was watching some classes now on youtube, and I made some tests that almost worked for what I want.
In this code, I cant edit one EditText and show a message in the 3 situations, before, on and after change the text.... and I did changes in the TextView created with AFTER, but just changed to a simple word, a text. That worked perfectly.
Now I'm trying to make a simple math, but I'm making some mistake with numbers and texts. I just need to multiply the EditText for a number (0.7354988) and put the result in the TextView, so I would convert CV to kW, but it gives me a message that I cant do it. I create one double CVtokWfactor with that value, but I'm not sure if I did it right.
this is the error:
Error44, 49) error: bad operand types for binary operator '*'
first type: EditText
second type: double
Below the JAVA:
Code:
package com.example.tbarata.textvalidation;
import android.app.Activity;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class TextValidation extends Activity implements TextWatcher{
EditText ed1;
TextView tv2;
double CVtokWfactor = 0.7354988;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_validation);
ed1=(EditText) findViewById(R.id.editText1);
ed1.addTextChangedListener(this);
tv2=(TextView) findViewById(R.id.textView2);
}
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
Toast.makeText(this, "before", Toast.LENGTH_SHORT).show();
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
Toast.makeText(this, "on change", Toast.LENGTH_SHORT).show();
}
@Override
public void afterTextChanged(Editable editable) {
Toast.makeText(this, "after", Toast.LENGTH_SHORT).show();
tv2.setText(String.format("%.2f", (ed1 * CVtokWfactor)));
}
}
What should I change to multiply these numbers ?
Thanks again.
Barata
Hello
For your first reply:
You have to put the code with the EditText inside the onCreate method. You made it work in the above code that you posted (outside onCreate) because you implemented the TextWatcher interface. You could avoid that by adding the code related with TextWatcher inside the onCreate method as I posted above
For your second reply:
In the afterTextChanged method, at
Code:
tv2.setText(String.format("%.2f", (ed1 * CVtokWfactor)));
You multiply the EditText ed1 with the double CVtokWfactor. You can't multiply an EditText with a number. The operand * needs numbers (int, double, float, etc )
You need to get the text of the ed1, convert it to double (I suppose edittext has double number) and then multiply, like this:
Code:
tv2.setText(String.format("%.2f", (Double.parseDouble(ed1.getText().toString()) * CVtokWfactor)));
Also I recommend to remove the Toasts from the methods beforeTextChanged, onTextChanged and afterTextChanged. They are called each time you type something on the EditText ed1.
If you still need help, feel free to ask
Hi!
Now it worked perfectly @MMDeveloper!! really thanks !
Agree with you about the Toast code, I forgot to delete it before paste here, it was just a test to see the events
About the way of using the TextWatcher, should I use the first way that you said, for some specific reason or basically both are the same ?
And now that's working, came the idea to improve the math, for an easy way of using it.
Now I can convert power in CV to kW, but lets say that I have one value in kW already, and need to convert to CV, would be posible using this same code/activity ? So I would convert in the same activity both units. Or, its gonna be some redundant thing ? My idea to save space, is use just the 2 fields, without one third to get the result.
This is the code now, already changed for a second EditText and not TextView anymore, until now it's working to convert the unit CV to kW, just when I clean out the EditTex1 field, the EditText2 keeps the conversion from the last number in the EditText1. Actually it's not a problem for now, the important is just convert it
Code:
public class Calc001Activity extends Activity implements TextWatcher {
EditText ed1;
EditText ed2;
double CVtokWfactor = 0.7354988;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calc001);
ed1=(EditText) findViewById(R.id.editText1);
ed1.addTextChangedListener(this);
ed2=(EditText) findViewById(R.id.editText2);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
try {
ed2.setText(String.format("%.2f", (Double.parseDouble(ed1.getText().toString()) * CVtokWfactor)));
}
catch (NumberFormatException e) {}
}
}
Thanks in advanced.
Barata.
Let's fix the issue with the old conversion first
When you clear the ed1 your
Code:
ed2.setText(String.format("%.2f", (Double.parseDouble(ed1.getText().toString()) * CVtokWfactor)));
}
should cause your app to crash, because Double conversion from an empty string would throw the NumberFormatException.
You are already catching it so it silently ignores it, and the ed2 is not updated.
To solve this just make a check:
Code:
@Override
public void afterTextChanged(Editable s) {
if(doNoEnterEd1==true){
return;
}
doNotEnterEd2 = true;
try {
if(ed1.getText().toString().equals("")){
ed2.setText("");
}
else{
ed2.setText(String.format("%.2f", (Double.parseDouble(ed1.getText().toString()) * CVtokWfactor)));
}
}
catch (NumberFormatException e) {}
doNotEnterEd2 = false;
}
Now it should clear the ed2 too, when you clear the ed1.
Now for the TextWatcher, you should do it as I mentioned in my first reply, only for having a separate TextWatcher for each EditText, but there is no problem with implenting the TextWatcher, as you did. Just for code clarity. Furthermore, for code clarity (and reusability), the text watcher should be in a separate Java class, but no need for such a small application So you are ok with that.
You can easily do the reverse conversion (from ed2 to ed1) as follows:
Inside your class outside any method, where you declared your EditText add:
Code:
boolean doNotEnterEd1=false;
boolean doNotEnterEd2=false;
in the onCreate method:
Code:
ed2=(EditText) findViewById(R.id.editText2);
ed2.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
if(doNoEnterEd2==true){
return;
}
doNotEnterEd1 = true;
try {
if(ed2.getText().toString().equals("")){
ed1.setText("");
}
else{
ed1.setText(String.format("%.2f", (Double.parseDouble(ed2.getText().toString()) * CVtokWfactor))); //Here do the conversion as you like, replace CVtokWfactor.
}
}
catch (NumberFormatException e) {}
doNotEnterEd1=false;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
I think it should work like intended now.
If you still encounter a problem feel free to ask
Hello!
@MMDeveloper, thanks man!!!
The code is working perfectly!! I changed the code as in the first reply and with these last modifications, its 100%!
Now I'm gonna improve the layout and add the others inputs for the math, but the base code is fully working
Really thanks for you time, helping me.
As reference, this is my code now (still without the improvement):
Code:
package com.example.barata.calc001;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class Calc001Activity_002 extends Activity {
double CVtokWfactor_2 = 0.7354988;
boolean doNotEnterEd1=false;
boolean doNotEnterEd2=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calc001_activity_002);
final EditText ed1_2 = (EditText) findViewById(R.id.editText02_1);
final EditText ed2_2 = (EditText) findViewById(R.id.editText02_2);
ed1_2.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(doNotEnterEd1==true){
return;
}
doNotEnterEd1 = true;
try {
if(ed1_2.getText().toString().equals("")){
ed2_2.setText("");
}
else{
ed2_2.setText(String.format("%.3f", (Double.parseDouble(ed1_2.getText().toString()) * CVtokWfactor_2)));
}
}
catch (NumberFormatException e) {}
doNotEnterEd2 = false;
}
});
ed2_2.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
if(doNotEnterEd2==true){
return;
}
doNotEnterEd1 = true;
try {
if(ed2_2.getText().toString().equals("")){
ed1_2.setText("");
}
else{
ed1_2.setText(String.format("%.3f", (Double.parseDouble(ed2_2.getText().toString()) * CVtokWfactor_2))); //Here do the conversion as you like, replace CVtokWfactor.
}
}
catch (NumberFormatException e) {}
doNotEnterEd1=false;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
}
public void vemPara001(View view) {
Intent vem001 = new Intent(this, Calc001Activity.class);
startActivity(vem001);
finish();
}
public void vaiPara003(View view) {
Intent vai003 = new Intent(this, Calc001Activity_003.class);
startActivity(vai003);
finish();
}
}
Thanks again!
barata.
Hi again!!
Sorry bring this topic back, but I gave up of doind my sliding tabs to get a nice layout in this app... so I got this one with a sliding menu from left, the I thought would be nice to use.
This is the link:
https://github.com/JulienGenoud/android-percent-support-lib-sample
Actually, the focus on its sample is to use the PERCENT lib, but that I don't care, just need to use the sliding menu;
I tried to replace the view1.xml for that with the code above (with textWatcher) and created one view_1.java with the codes, but nothing happens when I type a number in the editText....
Because the app uses a Drawer or fragment, should I change the way of doing that and automatically update the fields?
Thanks again!
Barata

[Q] How to update a textView every second.

I have a textview that shows your amount of money and i would like the ui to update every second to visually show how much money you have in real time. Would i be able to accomplish this with a timer?, and if so what would it look like.
Hello,
You should do inside your class, outside of any method:
Code:
TextView tv;
String calculatedString;
MyAsyncTask mAsync = null;
Timer timer = null;
TimerTask task = null;
private class MyAsyncTask extends AsyncTask<String, Void, String> {
public MyAsyncTask(){
}
@Override
protected String doInBackground(String... params) {
//Background operation in a separate thread
//Write here your code to run in the background thread
//calculate here whatever you like
calculatedString = ....;
return null;
}
@Override
protected void onPostExecute(String result) {
//Called on Main UI Thread. Executed after the Background operation, allows you to have access to the UI
tv.setText(calculatedString);
}
@Override
protected void onPreExecute() {
//Called on Main UI Thread. Executed before the Background operation, allows you to have access to the UI
}
}
inside the onCreate after super and setContentView:
Code:
tv = (TextView) findViewById(R.id.tv); //your tv id here
final Handler handler = new Handler();
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
MyAsyncTask mAsync = new MyAsyncTask();
mAsync.execute();
}
});
}
};
timer.schedule(task, 0, 1000); //Every 1 second
If you still need help, feel free to ask
I have attached 2 screenshots showing the errors i was given after inputting. Any idea how to fix this?
mmdeveloper10 said:
Hello,
You should do inside your class, outside of any method:
Code:
TextView tv;
String calculatedString;
MyAsyncTask mAsync = null;
Timer timer = null;
TimerTask task = null;
private class MyAsyncTask extends AsyncTask<String, Void, String> {
public MyAsyncTask(){
}
@Override
protected String doInBackground(String... params) {
//Background operation in a separate thread
//Write here your code to run in the background thread
//calculate here whatever you like
calculatedString = ....;
return null;
}
@Override
protected void onPostExecute(String result) {
//Called on Main UI Thread. Executed after the Background operation, allows you to have access to the UI
tv.setText(calculatedString);
}
@Override
protected void onPreExecute() {
//Called on Main UI Thread. Executed before the Background operation, allows you to have access to the UI
}
}
inside the onCreate after super and setContentView:
Code:
tv = (TextView) findViewById(R.id.tv); //your tv id here
final Handler handler = new Handler();
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
MyAsyncTask mAsync = new MyAsyncTask();
mAsync.execute();
}
});
}
};
timer.schedule(task, 0, 1000); //Every 1 second
If you still need help, feel free to ask
Click to expand...
Click to collapse
Hello,
For the first image:
You have to import the AsyncTask.
add this
Code:
import android.os.AsyncTask;
with the other imports in your java file.
For your second image:
You haven't wrote the line
Code:
setContentView(R.layout.activity_main);
under your super.onCreate(savedInstanceState); and then the code I said above (I said that on my post )
inside onCreate, where activity_main is your xml layout. And you should have inside that layout, a TextView with an id "tv" (or whatever you like)
and then:
Code:
tv = (TextView) findViewById(R.id.tv); //your tv id here
R.id.tv must much the id you have in your layout. Replace it with the actual id of your TextView. If your id is "tv", write R.id.tv, if it is "mytv" write R.id.mytv. ( I said that on my post also)
Can you show your layout file? (XML - your activity_main.xml). You said that you have a TextView Where is your TextView?
Ok I fixed the problems stated and now only have these two errors remaining
mmdeveloper10 said:
Hello,
For the first image:
You have to import the AsyncTask.
add this
Code:
import android.os.AsyncTask;
with the other imports in your java file.
For your second image:
You haven't wrote the line
Code:
setContentView(R.layout.activity_main);
under your super.onCreate(savedInstanceState); and then the code I said above (I said that on my post )
inside onCreate, where activity_main is your xml layout. And you should have inside that layout, a TextView with an id "tv" (or whatever you like)
and then:
Code:
tv = (TextView) findViewById(R.id.tv); //your tv id here
R.id.tv must much the id you have in your layout. Replace it with the actual id of your TextView. If your id is "tv", write R.id.tv, if it is "mytv" write R.id.mytv. ( I said that on my post also)
Can you show your layout file? (XML - your activity_main.xml). You said that you have a TextView Where is your TextView?
Click to expand...
Click to collapse
Have you imported this?
Code:
import java.util.logging.Handler;
If so, change it to
Code:
import android.os.Handler;
Im not at the computer but I think that should solve my issue I will keep you updated
Sent from my HTC6525LVW using XDA Free mobile app
Hey thanks so much its working perfectly now :good:

OnClickListener in a Fragment

Hi,
I'm new to Android development and I'm developing my first Android app about music that contains two fragments: Home Fragment and Genres Fragment. This app is a school project and it's kinda urgent.
In Genres Fragment, I have four ImageButtons and I want to add some action to them, like when clicking a button, it goes to another fragment
So, in the Java file of that fragment, I already have the code for OnClickListener but I don't know what to put in the case condition of each button.
P.S: I can't post images because is says: "All new users prevented from posting outside links in their message". So, instead of an image, I will post the code.
Code:
public class GenresFragment extends Fragment implements View.OnClickListener{
public GenresFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_genres, container, false);
ImageButton rapBtn = (ImageButton)v.findViewById(R.id.RapButton);
ImageButton popBtn = (ImageButton)v.findViewById(R.id.PopButton);
ImageButton edmBtn = (ImageButton)v.findViewById(R.id.EDMButton);
ImageButton rockBtn = (ImageButton)v.findViewById(R.id.RockButton);
rapBtn.setOnClickListener(this);
popBtn.setOnClickListener(this);
edmBtn.setOnClickListener(this);
rockBtn.setOnClickListener(this);
return v;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.RapButton:
break;
case R.id.PopButton:
break;
case R.id.EDMButton:
break;
case R.id.RockButton:
break;
}
}
}
Can you help me with this?
Thank you
Replace the fragment on button click
Hello,
you just need to replace the fragment on button click.
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Thanks!

New to Forum, New to Android

Hey ladies and gents,
I'm new to your forums, seems it will be a helpful resource as I undertake this new project. I'm not new to programming, but i'm rusty. About 20 years ago I started with Qbasic, in high school i moved on to Visual Studio and C++. But I have been out of it for awhile now.
I started learning a little python to help my dad with his own program. But Decided I wanted to use Android Studio for my own. I have already started looking into tutorials, but have yet to see some information I am looking for. ( Or just don't recognize due to inexperience )
Traditionally, whats best to use for a multiscreen App? I am currently running windows in Fragments. I have a sidescreen that pops out with a menu button (works), windows slide out with options ( works ), when you select the option the window slides away (works) and it brings up the fragment so you can fill in forms (works.)
Inside my Fragments java file I have this
public class ac extends Fragment {
private EditText od_input;
private EditText sp_input;
private EditText hp_input;
private EditText sl_input;
private EditText hl_input;
private EditText return_input;
private EditText vent_input;
private TextView diag_output;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public ac() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment ac.
*/
// TODO: Rename and change types and number of parameters
public static ac newInstance(String param1, String param2) {
ac fragment = new ac();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
EditText odtext;
EditText idtext;
EditText sptext;
EditText hptext;
EditText sltext;
EditText hltext;
EditText returntext;
EditText venttext;
@override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_ac, container, false);
// NOTE : We are calling the onFragmentInteraction() declared in the MainActivity
// ie we are sending "Fragment 1" as title parameter when fragment1 is activated
if (mListener != null) {
mListener.onFragmentInteraction("Air Conditioning");
}
// Here we will can create click listners etc for all the gui elements on the fragment.
// For eg: Button btn1= (Button) view.findViewById(R.id.frag1_btn1);
// btn1.setOnclickListener(...
//odtext = view.findViewById(R.id.odtext);
//idtext = (EditText) findViewById(R.id.idtext);
//sptext = view.findViewById(R.id.sptext);
//hptext = view.findViewById(R.id.hptext);
//sltext = view. findViewById(R.id.sltext);
//hltext = view.findViewById(R.id.hltext);
//returntext = view.findViewById(R.id.returntext);
//venttext = view.findViewById(R.id.venttext);
//TextView diagtext = view.findViewById(R.id.diagtext);
//diagtext.setText((CharSequence) odtext);
return view;
}
@override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// NOTE : We changed the Uri to String.
void onFragmentInteraction(String title);
}
}
Firstly, yes there is a lot of useless crapification going on. Was running different experiments and have not fully cleaned up yet.
But, as people type in the field I want to capture the inputs. Does this require a Listener? Can you capture as they type or do I need a button (Really, Really don't want a button)?
Also, I am unfamiliar with the layout of the java.
Oncreate is when the program boots up?
onCreateview is when the Fragment is booted up?
onattach is when the main activity is associated?
ondetach is when its associated from activity?
I don't fully understand yet where the best place is to add stuff, would it be after onattach?
Thanks for pointing me in the right directions guys.
Chris W.

Using Intent(send mail) in Navigation drawer

I want to send mail from Navigation Drawer using the intent. First, my MainActivity.
Code:
else if(id==R.id.nav_mail) {
fragment = new MailFragment();
}
and MailFragment.
Code:
public class MailFragment extends Fragment {
public MailFragment() {
Intent email = new Intent(Intent.ACTION_SEND);
email.setType("plain/text");
String[] address = {"********@gmail.com"};
email.putExtra(Intent.EXTRA_EMAIL, address);
email.putExtra(Intent.EXTRA_SUBJECT, "Subject___****");
email.putExtra(Intent.EXTRA_TEXT, "Text___****.\n\n");
startActivity(email);
}
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Bundle savedInstanceState) {
// TextView textView = new TextView(getActivity());
// textView.setText(R.string.hello_blank_fragment);
// return textView;
// }
}
Run to create crash. The reason why I used to use fragment is because I made the simple screen change function fragment.
If you need more code, comment plz.
I didn't get what you are trying to do. If you are trying to invoke the "Select your mail app" screen and then send a message thru the Intent all of this when the user clicks on a row on the drawer then you should just copy the code to
Code:
else if(id==R.id.nav_mail) {
// here
}
without switching any fragment.
By the way, as far as I know, the fragment's public constructor must be empty.
You cannot do it from Fragment's constructor. Move your code to onActivityCreated() method.
qlife1146 said:
I want to send mail from Navigation Drawer using the intent. First, my MainActivity.
Code:
else if(id==R.id.nav_mail) {
fragment = new MailFragment();
}
and MailFragment.
Code:
public class MailFragment extends Fragment {
public MailFragment() {
Intent email = new Intent(Intent.ACTION_SEND);
email.setType("plain/text");
String[] address = {"********@gmail.com"};
email.putExtra(Intent.EXTRA_EMAIL, address);
email.putExtra(Intent.EXTRA_SUBJECT, "Subject___****");
email.putExtra(Intent.EXTRA_TEXT, "Text___****.\n\n");
startActivity(email);
}
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Bundle savedInstanceState) {
// TextView textView = new TextView(getActivity());
// textView.setText(R.string.hello_blank_fragment);
// return textView;
// }
}
Run to create crash. The reason why I used to use fragment is because I made the simple screen change function fragment.
If you need more code, comment plz.
Click to expand...
Click to collapse
Creating a new Intent in the constructor is a really bad idea. An example from the android's developer guide
Code:
public class MainActivity extends AppCompatActivity {
public static final String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** Called when the user taps the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.editText);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}

Categories

Resources