В прошлой части мы смогли получить информацию о курсах валют с сайта ЦБ. Теперь нужно ее красиво подать пользователям. Для этого создадим графический интерфейс.
Мы воспользуемся инструментом RecyclerView. RecyclerView - это форматированный список, его отличие от обычного списка в том, что мы можем создать отдельный layout для элементов списка.
Заходим в Gradle Scripts -> build.gradle и в dependencies добавим строку:
implementation 'androidx.recyclerview:recyclerview:1.1.0'
Изменим макет activity_main добавив в него RecyclerView:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
Добавим строку в файл values -> strings:
<string name="previous">Предыдущее значение</string>
Теперь мы можем использовать переменную previous в наших макетах.
Следующим шагом создадим новый layout list_item который и будет макетом для одного элемента списка:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listView_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:id="@+id/tv_CharCode_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:textSize="20sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_Value_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_Previous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_Previous_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
Выглядеть в графическом редакторе это будет следующим образом:
Мы создали макет окна в котором будет отображаться список и создали макет для отображения одного элемента из списка. Следующим шагом нужно "подружить" эти макеты между друг другом.
Создаем класс адаптер для списка ListAdapter. Расширяем созданный класс с помощью RecyclerView.Adapter:
public class ListAdapter extends RecyclerView.Adapter<com.example.course.ListAdapter.ListViewHolder> {
ArrayList<Integer> arrayList = new ArrayList<>();
public void setItems(ArrayList<Integer> arrayList1) {
arrayList = arrayList1;
}
@Override
public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
int layoutIdForListItem = R.layout.list_item;
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(layoutIdForListItem, parent, false);
ListViewHolder listViewHolder = new ListViewHolder(view);
return listViewHolder;
}
@Override
public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
holder.bind(arrayList.get(position));
}
@Override
public int getItemCount() {
return arrayList.size();
}
}
Создадим вложенный класс ListViewHolder расширенный RecyclerView.ViewHolder:
class ListViewHolder extends RecyclerView.ViewHolder {
TextView nameItemView;
TextView CharCodeItemView;
TextView ValueItemView;
TextView PreviousItemView;
public ListViewHolder(@NonNull View itemView) {
super(itemView);
nameItemView = itemView.findViewById(R.id.tv_name_item);
CharCodeItemView = itemView.findViewById(R.id.tv_CharCode_item);
ValueItemView = itemView.findViewById(R.id.tv_Value_item);
PreviousItemView = itemView.findViewById(R.id.tv_Previous_item);
}
void bind(int position) {
nameItemView.setText("Имя " + position);
CharCodeItemView.setText("TEST " + position);
ValueItemView.setText("TEST = значение валюты TEST " + position);
PreviousItemView.setText("TEST = значение валюты TEST вчера " + position);
}
}
В данном классе найдем элементы на нашем макете (list_item), и в методе bind укажем этим элементам тестовые параметры с помощью метода setText.
Объект ArrayList нам пригодиться в будущем для передачи списка объектов (валют), на данном этапе создадим список чисел, равный количеству валют с сайта. Для этого изменим класс Main. Объявим несколько глобальных приватных переменных:
private ListAdapter listAdapter;
private ArrayList<Integer> arrayList;
private RecyclerView recyclerList;
В метод onCreate добавим:
recyclerList = findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerList.setLayoutManager(layoutManager);
recyclerList.setHasFixedSize(true);
Добавим в метод onPostExecute несколько строк:
int i = 0;
listAdapter = new ListAdapter();
arrayList = new ArrayList<>();
В этом же методе в цикл while:
i++;
arrayList.add(i);
И удалим не нужный нам теперь вывод в консоль.
После цикла добавим две строки:
listAdapter.setItems(arrayList);
recyclerList.setAdapter(listAdapter);
Мы передаем нашему списку массив элементов (в данном случае чисел от 1 до 34) для отображения на экране смартфона.
После всех манипуляций получим метод onPostExecute следующего вида:
protected void onPostExecute(String response) {
int i = 0;
listAdapter = new ListAdapter();
arrayList = new ArrayList<>();
String Name = "";
String CharCode = "";
String Value = "";
String Previous = "";
try {
JSONObject jsonResponce = new JSONObject(response);
JSONObject jsonObject = jsonResponce.getJSONObject("Valute");
Iterator<String> keys = jsonObject.keys();
while (keys.hasNext()) {
String key = keys.next();
Name = jsonObject.getJSONObject(key).getString("Name");
CharCode = jsonObject.getJSONObject(key).getString("CharCode");
Value = jsonObject.getJSONObject(key).getString("Value");
Previous = jsonObject.getJSONObject(key).getString("Previous");
i++;
arrayList.add(i);
}
listAdapter.setItems(arrayList);
recyclerList.setAdapter(listAdapter);
} catch (Exception e) {
e.printStackTrace();
}
}
Запустим наше приложение и посмотрим на результат наших трудов:
В первой части мы получили данные с сайта, во второй части мы создали список для вывода этих данных, осталось соединить...