Hello to all habrovchanam! I am glad to inform you that the company in which I work, has released the app "Caucasian cuisine" under Android. Now your favorite dishes are always at your fingertips. I have been involved in almost the entire application development process and would like to share the details with you. First I want to talk about the application itself, and in the second part of the article about the problems encountered during the development and possible solutions. As a result, those who are interested in the application can read the first part, and those who are interested in the second development process. Go!
Application OverviewScreenshots and the application itself can be viewed as usual in the market -
market.android.com/details?id=net.octobersoft.android.caucasiancuWith the application, you can quickly find your favorite recipe and method of preparation (in the database a little more than 200 recipes). In addition, with the help of an assistant, you can quickly find recipes for the products you have, with a hint how many ingredients are contained in the found recipe. With the help of the basket, you can save the products you need, or add your own, after which, starting cooking any recipe, set a timer and roll up your sleeves to start cooking. You can add ingredients to the basket when viewing the recipe (in the first tab after selecting the recipe category and favorite recipe), and new products added to the basket will be displayed in the assistant with all the others. And of course, all the favorite recipes can be kept in your favorites, for quick access to them. When you select all the recipes, a search bar appears that helps you quickly find the right recipe. This is such a handy application that will help you prepare your favorite dish.
')
I will add that the version of the application will be updated soon, in which it will be possible to share thoughts about using the application with your friends via Facebook, Twitter or VKontakte and a couple of other buns.
If you notice any bugs, please write about this in the comments or mail.
Development. Difficulties and possible solutionsTabs and several windowsAs you can see, the application is navigated using tabs. But in many tabs there are several windows. The difficulty lies in the fact that if you do not clean the running windows during transitions, then the hierarchy of the views will increase the allowable value and the application will fall. To do this, you can create your own class inherited from TabActivity (which inherits the main application window, where all the tabs are), which will override onBackPressed () as needed, or call yourself finish () during transitions.
Also, there was a problem with customizing the appearance for a single tab. In fact, there is nothing complicated about it, you just write your layout with views and style it by passing it to the tab as you like.
Activation statesAccording to some authors, most often (and all that you basically need) are used onCreate (by itself), onStart () and onPause (). Yes, indeed it is, but in our application, the timer also works in the background and when the window is destroyed (when onDestroy () is called, it resets the state to the database in order to resume when the application starts). The authors of Pro Android 2 claim that this method may not be called into everything, like onStop (), so be careful and study the window's life cycle thoroughly. It was possible to write a service for the timer, as a solution to problems, but then there could be others.
Gradient imagesSome images in our application contain gradients and by default (at least in my emulator and on real devices) the gradients spread out into bands, which looks scary. Solving the problem as it turned out simple: set the window palette. And you can do this by overriding the onAttachedToWindow () activation method by adding the following lines to the method:
super.onAttachedToWindow(); // !
Window currWind = getWindow();
currWind.setFormat(PixelFormat.RGBA_8888);
Do not forget about HandlerIf you need to display something in the UI stream, and you are not in the context of activation (this is certainly not the Android way), you will not be able to do without this class. Another option is to use AsyncTask. Although the options for using this class are much larger (for example, the queue of threads that update UI elements).
Calling keyboard events programmaticallySometimes this may be required and solved for example:
new BaseInputConnection (txtView, false) .sendKeyEvemt (backPressedKeyEvent);
I am sure there are other ways, but the code above helped me to return to the previous window after an unsuccessful search.
SQLite cacheSQLite caches data. You just need to remember this during the development of the application and put a tick wipe user data (if you want to update the data). At one time, I spent several hours understanding why this is so without knowing this feature.
ListsInherit from ListActivity or not? In fact, the only difference is whether the window design requires other elements and the layout itself. If yes, then inheritance is not what you need, if not, then inherit the class and you do not need to call setContentView.
Also remember one important thing about lists. The list reuses the elements of the view, so you need to work with it carefully. You can, for example, use the twist: setTag (), getTag () methods to bind arbitrary identifiers. You should also be careful about writing a custom adapter and using the convertView parameter in the getView () method, and I wrote about it actually!
Another problem when working with lists was the incorrect display of list items in ScrollView.
The layout includes such a piece:
...
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:src="@drawable/icon"
android:id="@+id/recipe_img"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:layout_weight="0"/>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none"
android:divider="#00000000"
android:cacheColorHint="#00000000" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="2"
android:gravity="center"
android:scaleType="fitXY"
android:src="@drawable/cook"/>
...
In this version of the design, the elements of the list are truncated and not all are visible (in my opinion there are such issues on Googlecode)
The solution to the problem was to set the size of the list by the number of elements in it, the code below:
//set ListView size by items count
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
DialoguesWhen writing a custom dialog (inheriting the Dialog class), a difficulty arose: the buttons were easily found by findViewById () and worked correctly, but the EditText widget was not (the method returned null). As usual, LayoutInflater was used to search for the root element. The solution was simple - create a Dialog class, pass the required layout and then call the findViewById () dialog. And by the way, the application context could not be transferred as I did not try, because the dialogs are tied to the current activation. But I still suspect that this problem can be solved!
Do not reinvent the wheelMany ready-made classes and applications already exist in Android, and therefore it is better to first look carefully at the dock or google.
Use LogCatLogging helps to quickly find a bug during development (especially using its filters in Eclipse) and view the necessary output of activations, services, etc., so always use it. But logging should be removed from the release version (as Google says), although a bunch of standard services and applications on the device are still being written to the log!
SQLite ManagerI used this plugin for Firefox 3.x to work with the sqlite database. It is free, convenient, functional (you can write procedures, look at table structures, data, execute queries, etc.). So I would recommend to anyone who does not know or wants to choose such a tool, for developing it. Although a bunch of alternatives!
Application Size LimitThis is the funniest item. On the day, or more precisely, the hour of release to the market, we learn that the application can not be more than 50MB, and our weight is 79! Thank you Google for such a chip ... because of this, I had to make not the most pleasant decision ...
ScreenshotsThis is a window with recipes in the selected category:

Screen with all categories of recipes:

Screen selected recipe:

And this is the window with timers:
ConclusionI emphasize that my recommendations can be challenged, since I am not a guru on Android (this is my first application and part-time first post on Habré) and there are often several ways to solve one problem in the platform, but the considered tips work and it pleases! I support the call for the exchange of experience, which was already on Habré.
Otherwise, the development process was approximately the same as in web applications: a data model is written, CRUD operations for this model, an interface, and the necessary functionality. The difficulties were unknowingly the Android platform and the lack of experience in creating applications for mobile platforms.
Comments and suggestions on the topic in private messages.
Thanks for attention!
UPD Now the application is available in the free version:
market.android.com/details?id=net.octobersoft.android.caucascureefree