问题
I'd like to use a TextView to log some actions in my app. Is the following method bad practice (are there any drawbacks?)
TextView tv = (TextView)findViewById(R.id.textView);
String s = "";
s = s + "Starting app...\n";
tv.setText(s);
...
s = s + "Doing action #1.\n";
tv.setText(s);
...
s = s + "Doing action #2.\n";
tv.setText(s);
Is there a better way to do it than redo a setText(s) each time, after having appended the new logging information to s ?
回答1:
There's a pretty clean approach, which is to use DataBinding in android. I will go through a short example of how your use case might end up looking.
First, to use DataBinding you must enable it from the build.gradle of your app:
android {
dataBinding {
enabled = true
}
}
Second thing would be to create a model that would contain your log message, this is also a clean way to store the message instead of simply appending to a string. In my case, I'll call it Log:
public class Log extends BaseObservable{
//This will be the message you wanna print
private String message;
@Bindable
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
//This would automatically update any binded views with this model whenever the message changes
notifyPropertyChanged(BR.message);
}
}
Third thing would be to update your layout file which contains the TextView you're using. Basically, we'll create a Log variable in the layout, and tell the textView to read the message from it and display it as its text. In my example, activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="log"
type="com.riad.crypto.databinding.Log" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:textSize="18sp"
android:text="@={log.message}" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_view"
android:gravity="bottom"/>
</LinearLayout>
Now simply, wherever you wanna display the logs, create a Logger object and bind it with the textView. In my example MainActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Log logger = new Log();
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setLog(logger); //This is where we bind the layout with the object
Button button = (Button) findViewById(R.id.button_view);
logger.setMessage("1st log statement"); //You'll notice that the texview displays this message first
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
logger.setMessage("2nd log message"); //After button click, the texview would automatically change text to this. All you did was set the message
}
});
}
So now you could change the textView on every button click, but ofcourse you could do it wherever you want. And in case you need the Log object in different classes you could improve this by creating a Singleton or something, but this was just for the demo.
Hope this helps! Goodluck
来源:https://stackoverflow.com/questions/47743184/log-informations-in-a-textview