📜 ⬆️ ⬇️

Android development and problem solving related to development

Purpose of the article


This article will address the problems of Android development and development in general. We all know that developing a program is a lot of hard work that takes a lot of time and effort, and sometimes you have to spend a lot of time to find a solution to a problem, because some solutions from the Internet do not always work.

This article will address the following questions:


Custom keyboard for Android


In my program, in my calculator, I had to make my keyboard, because it was not very convenient to enter mathematical formulas from the system keyboard. Trying to solve this problem, I went through a bunch of forums, tried out several different solutions, but they all did not give the proper result.
')
Let's start:
  1. Create a new project in android studio.
  2. Create a couple of classes.
  3. Test the application

Make a simple keyboard of 9 characters with the ability to delete these characters.
Let's call our project KeyBoardTest



Select an empty activity and start



Done we created our new project. Now let's do the most basic, namely, create a layout file in the folder - res / layout and name it keyboard, here we will have the appearance of the keyboard.

Let's draw this keyboard:

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_gravity="bottom" android:background="@color/colorBlue" android:layout_width="match_parent" android:layout_height="100dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <TextView android:id="@+id/one" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/one" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/two" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/two" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/three" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/three" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/four" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/four" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/five" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/five" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <TextView android:id="@+id/six" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/six" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/seven" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/seven" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/eight" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/eight" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/nine" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/nine" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/delete" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/delete" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> </LinearLayout> </LinearLayout> </FrameLayout> 

After our keyboard is drawn, we can create a class that will register all of our keystrokes and write what we need. Please note that every textview has an id - this is very important!

Let's call this class KeyBoardListener.

Let's write the constructor of our class, it takes as a argument the View - the field in which we work, in other words, the location of our editText, and also it accepts the editText itself, in which we will type characters from our keyboard.

 package keyboard.develop.keyboardtest; import android.view.View; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; public class KeyBoardListener { EditText editText; private StringBuilder finalText = new StringBuilder(); KeyBoardListener(View view, final EditText editText) { this.editText = editText; TextView one = view.findViewById(R.id.one); TextView two = view.findViewById(R.id.two); TextView three = view.findViewById(R.id.three); TextView four = view.findViewById(R.id.four); final TextView five = view.findViewById(R.id.five); TextView six = view.findViewById(R.id.six); TextView seven = view.findViewById(R.id.seven); TextView eight = view.findViewById(R.id.eight); TextView nine = view.findViewById(R.id.nine); TextView delete = view.findViewById(R.id.delete); final LinearLayout layout = view.findViewById(R.id.keyBoard); one.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "1"); setTextSelection(); } }); two.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "2"); setTextSelection(); } }); three.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "3"); setTextSelection(); } }); four.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "4"); setTextSelection(); } }); five.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "5"); setTextSelection(); } }); six.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "6"); setTextSelection(); } }); seven.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "7"); setTextSelection(); } }); eight.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "8"); setTextSelection(); } }); nine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "9"); setTextSelection(); } }); delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); if (finalText.length() > 0) { finalText = stringToBuilder(finalText.substring(0, selection - 1 == -1 ? 0 : selection - 1) + finalText.substring(selection)); editText.setText(finalText); } editText.setSelection(selection - 1 <= 0 ? 0 : selection - 1); } }); editText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { layout.setVisibility(View.VISIBLE); } }); } private StringBuilder stringToBuilder(String s) { return new StringBuilder(s); } private void setTextSelection() { int selection = editText.getSelectionEnd(); editText.setText(finalText); editText.setSelection(selection + 1); } } 

Now let's take a closer look at this code. In the constructor we passed the editText and view in order to take the buttons and assign them the execution of the input. It should be noted that the method of the delete button uses "syntactic sugar", in other words, it is an abbreviated entry of the code. Not everyone knows this design, so I decided that we should pay attention to it. This is especially useful for beginners.

This construction works in this way.

 int p = () ?  1 :  2; int p = k == 2 ? 7 : 3; //      if (k == 2) p = 7; else p = 3; 

But we have moved away from the topic. Now after our constructor is ready, and we can respond to button presses, we can use our class. First we need to call this class in our main activity.

 package keyboard.develop.keyboardtest; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.view.WindowManager; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private LinearLayout layout; private ExecutorThread executorThread; @Override protected void onCreate(Bundle savedInstanceState) { getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); //   ,     super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText editText = findViewById(R.id.edit); layout = findViewById(R.id.keyBoard); new KeyBoardListener(layout, editText); executorThread = new ExecutorThread((TextView)findViewById(R.id.textView)); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void afterTextChanged(Editable editable) { if (!editable.toString().equals("")) { executorThread.setK(Integer.parseInt(editText.getText().toString())); executorThread.doWork(); } } }); } @Override public void onBackPressed() { layout.setVisibility(View.GONE); //   } } 

It is worth paying attention to this line.

 getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 

In this line, we disable the system keyboard, but leave the cursor so that we can move between characters and insert numbers / letters, etc. That is precisely why we used the StringBuilder class and the insert method in the code above.
Due to the fact that this whole method is called as a separate class, we can add it anywhere and use it in any programs. Thus, the objectivity of the code is obtained.

But I didn’t show you how to do it in xml code, how to specify the location of this keyboard, and everything is very simple

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout 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" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="keyboard.develop.keyboardtest.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:textColor="@color/colorPrimary" android:gravity="center" android:textSize="25sp" android:layout_width="match_parent" android:layout_height="50dp" android:text="Write your text here!"/> <EditText android:id="@+id/edit" android:layout_width="match_parent" android:layout_height="50dp"/> </LinearLayout> <LinearLayout //       android:visibility="gone" android:id="@+id/keyBoard" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_gravity="bottom"> <include layout="@layout/keyboard"/> //   ,    </LinearLayout> </FrameLayout> 

Now with light manipulations we can use our keyboards anywhere, even in fragments.

In our application, the keyboard looks like this



Multithreading


Multi-threading - it is clear from the name that this is a lot of threads. A lot of threads - this means the execution of several operations simultaneously. Multithreading is a rather problematic topic in programming. What's in C ++, what's in Java, that in other languages ​​with multithreading there have always been problems. Fortunately, almost all languages ​​have a high-level solution to this problem. But we are currently developing for Android, so we’ll talk about Anroid, or rather, the Java programming language.

In Java, Java has such a thing as Thread - it is convenient when drawing, with frequent instant redrawing of the image, there are many articles on this topic, including on Habré, so I will not consider this option. I am interested in the so-called - “sleep flow”, the flow that is waiting for its call to solve any task. This is the case when you caused the flow, it worked and fell asleep, without spending the device resources while waiting for a new task.

And the name of what I described above is a class from the standard java.util.concurrent package ExecutorServise

The essence of this class is that it can reuse the same stream without creating a new one. And now let's consider how it works, we will not create a new program, but continue to work in ours.

To do this, create a new class, which will be called ExecutorThread. Let us set the task that we need to add one to the digit p , until this p is equal to the number entered by us in 4 degrees. Everything is done to make the calculation longer. And so that the whole interface does not hang, we will put it all into a separate thread.

 package keyboard.develop.keyboardtest; import android.widget.TextView; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ExecutorThread { private ExecutorService executorService; private Thread thread; private int p = 0; private int pow = 0; private int k = 0; private TextView textView; ExecutorThread(final TextView text) { p = 0; textView = text; thread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < pow; i++) p++; String s = "Result " + k + "^4 = " + String.valueOf(p); textView.setText(s); } }); thread.start(); executorService = Executors.newSingleThreadExecutor(); } void doWork() { executorService.submit(thread); } void setK(int k) { p = 0; this.k = k; pow = (int) Math.pow(k, 4); textView.setText("Please wait. We are calcing!"); } } 

As we see, at that moment, while we did not consider it yet, then we can see the entry “Please wait. We are calcing! ”, That is clear -“ Please wait. We believe!". And after we calculate, we will display the text in our textView, which we passed to the constructor of our class. In order for everything to work, we need to add textView after our editText to our activity_main, which we had when creating the project.

 <TextView android:gravity="center" android:textColor="@color/colorPrimary" android:textSize="25sp" android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="50dp"/> 

And we also need to add the code below to our main class, MainActivity.

 executorThread = new ExecutorThread((TextView)findViewById(R.id.textView)); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void afterTextChanged(Editable editable) { if (!editable.toString().equals("")) { executorThread.setK(Integer.parseInt(editText.getText().toString())); executorThread.doWork(); } } }); 

It is worth noting that the addTextChangeListener method is responsible for changing the text in our editText. As we can see, inside this method we call the doWork () function, which in turn executes these strings

 executorService.submit(thread); 


I checked all the above on my phone, so if you did everything right, then you should have no problems or errors.

As we can see, this method is quite convenient and easy to understand, I tried to describe everything as simply as possible, so I hope you understand everything, but I did not miss anything.

And now let's move on to point 3 of our article, namely, the integration of advertising.

Advertising integration


In fact, I can’t tell you much about this, I can only advise. With advertising, not everything is so easy and transparent. Personally, I would advise you to use Appodeal, it is not so long ago on the market, but it works quite successfully.

It is also worth noting that there is a very good Russian-language support, which almost always immediately answers your question or your problem. This immediately makes it clear how loyal this network is.

I want to say right away, if you suddenly use it, be sure to set up payment in AdMob and in Appodeal, otherwise the advertisement will simply not be loaded. Due to the fact that I did not set up accounts, I wasted all day, and then they told me in support: “Did I set up accounts?”. And after I did it, the advertisement appeared 2 hours later.

Conclusion

Since this article is intended for novice programmers, I want to note one obvious thing. If you really like programming, and you are ready to spend tons of hours on solving a particular problem, then programming is yours, otherwise there isn’t. Just do not go beyond. Since it’s too long a decision, something not too complicated and not too simple is not good. But this is an obvious fact. In fact, I read this phrase somewhere on the Internet. In fact, it is true. If you think about it, then really, if programming, serious programming would be so easy, then few people from the total number of all people would be involved in it.

I hope that my article turned out to be useful to someone and really helped someone, helped save time, because I personally, on the keyboard, it would seem such a simple thing, killed 3 days, and it took me 2 streams and the search for a normal solution. of the day

Source: https://habr.com/ru/post/426223/


All Articles