Faster and shorter way of finding views - android

Is there a quicker or shorter way to initialize all view in my layout than this:
row2[0] = (RelativeLayout) findViewById(R.id.ll22);
row2A[0] = (RelativeLayout) findViewById(R.id.ll22alt);
row2B[0] = (RelativeLayout) findViewById(R.id.ll22blank);
mOffsiteDataBackup[0] = (TextView) findViewById(R.id.ll22_backup);
mRam[0] = (TextView) findViewById(R.id.ll22_ram);
mCpu[0] = (TextView) findViewById(R.id.ll22_cpu);
mHdd[0] = (TextView) findViewById(R.id.ll22_hdd);
mOs[0] = (TextView) findViewById(R.id.ll22_system);
mStatusIcon[0] = (ImageView) findViewById(R.id.ll22_image);
.
.
.
It is really annoying to write lot of lines only to find views. Until I find all of them and initialize some listeners, my onCreate has more than 400 lines, which is something I certainly don't want.
Thanks for your tips !

Any way you do it it's going to be around the same amount of typing, in some cases even more. 50> an extreme amount of views in an activity...
The only way I can think of making this smaller is splitting them up into Fragments and use the updated framework... 70 elements shouldn't be in one ui.. a ui is meant to be simple and easy to use. Not with lots of elements to it that distracts the user from the main task they want it for.

If few UI elements are functional unity(like your progresBar and textView), you can create custom view with these elements. That makes code is much more clear, especially if you use more instances of this view in one activity.

Related

Which of the two code is better on memory basis?

I am learning android development from a course by Udacity.While I was going through the Lesson 2,there came a situation where we had to create multiple Textviews,set the text from previously created ArrayList of strings and add those Textviews to Linear layout.
Common code:
ArrayList<String> words = new ArrayList<String>();
words.add("one");
words.add("two");
words.add("three");
words.add("four");
words.add("five");
words.add("six");
words.add("seven");
words.add("eight");
words.add("nine");
words.add("ten");
LinearLayout rootView =(LinearLayout) findViewById(R.id.rootView);
Now what they did:
for(int i=0;i<10;i++){
TextView wordView=new TextView(this);
wordView.setText(words.get(i));
rootView.addView(wordView);
}
What I did:
ArrayList<TextView> wordView = new ArrayList<TextView>();
for(int i=0;i<10;i++)
{
wordView.add(new TextView(this));
wordView.get(i).setText(words.get(i));
rootView.addView(wordView.get(i));
}
Now,my question is weather my way to approach the task has more memory overheads than their way?
I feel my code is better because I have reference to each TextView even after the loop.
No difference. In both cases TextView instances could not be garbage collected, so memory foot print is equal.
because I have reference to each TextView even after the loop.
If you don't really need these references then it's just senseless. It's not memory related advantage.
Your code looks good. But I don't see a point on having 10 the same TextViews. I would consider using a listView or recyclerView if you are using it as a list and thinking about optimising your code.
But still your code is fine.
It doesn't matter performance wise.. Just like you said:
I feel my code is better because I have reference to each TextView even after the loop.
If you need that, do it..

Easier way to declare a lot of Views

I'm trying to build a timetable app and there I will need a lot of dynamical Textviews, the only way I know is to declare every Textview for it self like
MoFa1 = (TextView) findViewById(R.id.MoFa1);
MoFa2 = (TextView) findViewById(R.id.MoFa2);
MoFa3 = (TextView) findViewById(R.id.MoFa3);
MoFa4 = (TextView) findViewById(R.id.MoFa4);
MoFa5 = (TextView) findViewById(R.id.MoFa5);
MoFa6 = (TextView) findViewById(R.id.MoFa6);
MoFa7 = (TextView) findViewById(R.id.MoFa7);
MoFa8 = (TextView) findViewById(R.id.MoFa8);
MoFa9 = (TextView) findViewById(R.id.MoFa9);
MoFa10 = (TextView) findViewById(R.id.MoFa10);
Now I want to know if there is another easier way to declare multiple views.Thanks in advance
How are your views displayed? Since you're creating a timetable I think your views are displayed in a grid. You can use GridLayout or you can use a RecyclerView. Here its an excellent article about using RecyclerView.
EDIT: Here its another article using RecyclerView with GridLayoutManager
I don't know how they are displayed, but you could use a gridlayout and add them dynamically by looping throught cells.
http://www.techotopia.com/index.php/Working_with_the_Android_GridLayout_in_XML_Layout_Resources
http://android-er.blogspot.ca/2014/09/insert-view-to-gridlayout-dynamically.html?m=1
If these links actually help you, I will describe its content here.
Use butter knife http://jakewharton.github.io/butterknife/
#BindView(R.id.MoFa5) TextView mofa5;
That's it. No findviewbyid.

how to exchange data between activity and layout xml in android

I need to exchange data between activity and it's layout xml in Android. But I do not find a way to do this in Android. For example, views and controller in mvc pattern always has a way to exchange data between. So I am wondering is there any way to exchange data between them to should I refresh my mind and realize there is no such way?
use below code to get value from layout in your activity
String value;
EditText editText= (EditText) findViewById(R.id.editText);
value=editText.getText();
code in xml example:
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
in java class (like onCreate()):
ImageView image = (ImageView) findViewById(R.id.image_view);
Then you can do what you want with image
I believe you're unsure exactly what you're asking. If you want to exchange information, such as ID or text entered into a textfield then any good android tutorial should be-able to demonstrate this. Considering your last comment I think you're talking about GET and POST based technologies which can be done usingREST andSOAP, or both if you want.
This questions answer has a good implementation and definition of what both of these webservices are.
P.S. If this is what you're looking for then upvote that answer.
As some additional info, the "view" (XML Layout file) gets set by your activity initially on your activity's onCreate method. Right after you call it's parent method (super.onCreate()).
To maintain scope throughout the activity I tend to declare all the layout widgets that I need to the activity to interact with outside of any methods and within the class.
TextView textWelcomeMessage;
public void MyActivity(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// before calling setContentView() we have the option to change
// window features ex requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_my_activity);
// Now to set the textview
textWelcomeMessage = (TextView) findViewById(R.id.textWelcomeMessage);
// Set some data
textWelcomeMessage.setText("Hello, welcome to my activity");
}
It's not exactly like traditional php style mvc since static typing changes thing up a bit and we have to worry about scope. But the core principles can still apply as far as data abstraction and separation go. Hope this helps =)

Multiple TextViews update very slowly

I have a Service that sends an Intent to my Activity every 0.1 seconds. I use it to update a custom implementation of a Chronometer. Here everything goes right. The problem comes when I want to update 14 TextView I have in a TableView inside a Fragment in my Activity. Here the app is very slow.
The method in my Activity where it receives the Intent from the Service:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long milis = intent.getLongExtra("milis",0);
if( mFragment != null)
mFragment.Update(milis);
}
};
The code inside the Fragment where I update the TextViews:
public void actualizarTiempoJuego(long milis){
// Se recuperan los tiempos acumulados y se aumenta la cantidad pasada como parámetro
for(int i=0;i<7;++i) {
long mCurrentMilis1 = mVectorMilis1.get(i);
long mCurrentMilis2 = mVectorMilis2.get(i);
TextView1 t1 = mListaTitularLayoutLocal.get(i);
TextView1 t2 = mListaTitularLayoutVisitante.get(i);
t1.setText(String.value(milis + mCurrentMilis1));
t2.setText(String.value(milis + mCurrentMilis2));
}
}
Am I doing anything wrong, or is it just that I'm trying to do something very complex in terms of efficiency?
#Sherif brings up a good point about hidden alpha values that bog down your application a lot.
Depending on your platform you may also want to check
<application android:hardwareAccelerated="true"... />
Another thing you can look into that may help performance is not firing off all those Intents. Once you start firing intents you are getting the system involved and depending on how they are getting resolved it may take some extra time.
For this issue I like to use Handlers. They are more light weight than intent.
You may also want to look at AsyncTask. This is basically like a thread, but also gives hooks that run on the UI Thread so you can perform both perform a background operation and update the UI without have to post runnables.
EDIT: Lastly, you can always run your layouts through the layoutopt tool. I was personally told by Romain Guy himself that if your drawing too slow, than you need to draw less. Just check out a screenshot (from a less than ideal view tree, but well within the max) from the profiling tool. You can see how much of the resources view drawing takes up. It's very important to keep this as lean as possible if you want your app to be responsive.
EDIT: It is no longer called layoutopt, it's called lint. Check your ~/android-sdk/tools/
I have once faced a situation where a fragment was really slow.
I am just predicting that your fragment has some kind of alpha and it is drawn on a 'heavy' activity.
The conclusion is that each time you are setting the text of a textview your whole view hierarchy is being invalidated.
It seems that fragments have this flaw. Anyway, use some layout instead of the fragment and check if it remains 'slow'.
ADDITION: A wrap_content textview will cause much more delay after a setText than a fill_parent textview.
You're likely running into slowdowns due to layout management with TableLayout and TextView. Every time you update text in one of those, a large amount of view measuring has to take place in order to put the characters in the right place on the screen. You should really just profile the app yourself using Traceview to find out. More information at: http://developer.android.com/tools/debugging/debugging-tracing.html
I've had the exact same issue you're seeing with the same type of layout (Fragment > TableLayout > Multiple TextViews). One way to test if your TableLayout/TextView setup is to blame is simply replace all that with a single TextView. That will probably run pretty well. Then put your 14 views into a FrameLayout or RelativeLayout. Even if they all overlap, you should still get decent performance, because it's the complexity of the TableLayout view measurements that's really causing slowdown.
As someone said you can use HardwareAccelerated but this is not a great solution, you will waste ram and cpu if you can't solve it in a different way. A solution probably more safety is to reduce the number of TextView. Try to reduce 14 to 7 and it will go twice faster. Usually is hard to do it but if you put the objects in a strategy position a pair of TextView one above other can be together if you make a TextView with two lines. And don't forget that findViewById is so expensive, if you will use a view object often find it one time and hold its reference.
Benchmarks are always useful for determining where slowness actually comes from, but I feel pretty confident suggesting that sending an Intent is probably much slower than updating 14 TextViews. Sending 10 Intents per second is a sign that you're Doing It Wrong (TM). This is just isn't what they're for.
Am I doing anything wrong, or is it just that I'm trying to do something very complex in terms of efficiency?
Updating 14 TextViews per second isn't inherently complex; you should be able to easily achieve this with a more appropriate application design. ASyncTask or Handler come to mind as possible tools, but it's hard to know what's best without knowing more about exactly what you're trying to do.
You can try to declare vars outside the loop :
public void actualizarTiempoJuego(long milis){
// Se recuperan los tiempos acumulados y se
// aumenta la cantidad pasada como parámetro
long mCurrentMilis1;
long mCurrentMilis2;
TextView1 t1;
TextView1 t2;
for(int i=0;i<7;++i) {
mCurrentMilis1 = mVectorMilis1.get(i);
mCurrentMilis2 = mVectorMilis2.get(i);
t1 = mListaTitularLayoutLocal.get(i);
t2 = mListaTitularLayoutVisitante.get(i);
t1.setText(String.value(milis + mCurrentMilis1));
t2.setText(String.value(milis + mCurrentMilis2));
}
}
And to setText() with mixed type, you can try setText("" + milis + mCurrentMilis2);

Create dynamic tables in android. New view vs inflater

I would like to create dynamic table in android (custom number of rows and columns). Minimum sdk is 3.0
I suppose to crate it via one of 2 ways:
1) via creating new TextView
TableRow tr = ....;
for ( i = 0; i < NumOfRows .... ) {
TextView tv = new TextView(this);
tv.setLayoutParams(...);
tv.setText("Text I wanna to see");
tr.add(tv);
}
2) via inflater
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for ( i = 0; i < NumOfRows .... ) {
TextView tv = (TextView) mInflater.inflate(R.layout.my_cell_layout, null, false)
.findViewById(R.id.my_cell_item);
tv.setText("Text I wanna to see");
tr.add(tv);
}
3) Your way :)
What is faster? What should I select?enter code here
It's all as per your requirement that which is better.
from link http://www.aslingandastone.com/2010/dynamically-changing-android-views/
Because layouts can be created either in XML or in code, you could probably make do without ever having to do dynamic XML layout loading. That being said, there are some clear advantages as to why I think one may want to do so:
Code cleanliness. Doing anything more than basic layouts in code can get very messy, very fast.
Code re-use. It’s extremely easy to inflate an XML layout into a specified view with one or two lines of code
Performance. Creating the objects necessary for an in-code layout leads to unnecessary garbage collection. As per the Android Designing for Performance article, “avoid creating short-term temporary objects if you can.”
Attribute availability. Defining Views in an XML layout exposes attributes that are not always available by object methods.
*
Possible disadvantages:
It make take more time to do an XML layout versus defining the layout in code, especially if there are only one or two interface elements that need to be changed.
*
To find out which is faster, implement both methods and use the method profiling utility, TraceView. That being said, its easier to maintain an XML file when making changes than it is to modify code. So, if I were you, I would prefer technique #2.

Categories

Resources