Урок 16. Улучшение UI поведения на экране UserInfo – Devcolibri – Android для начинающих

Урок 16. Улучшение UI поведения на экране UserInfo

Структура урока:

Улучшение UI поведения

Давайте ещё раз внимательно посмотрим на наше приложение. Особенно на прокрутку списка твитов. Очень странно выглядит, что наш верхний блок с информацией
о пользователе всегда остаётся на месте, закрывая при этом основную часть экрана. Давайте исправим это.

Вот как выглядит прокрутка списка сейчас:

 

AwfullRecyclerView.png

 

Для того чтобы это исправить, будем использовать контейнер NestedScrollView, т.к. мы хотим чтобы наш верхний блок также прокручивался, чтобы не занимать
рабочую область экрана. Давайте изменим наш activity_user_info.xml:

 

activity_user_info.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        style="@style/Toolbar"/>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="8dp">
                <!-- информация о пользователе не изменилась  -->

            </RelativeLayout>

            <View
                android:id="@+id/delimeter_view"
                android:layout_width="match_parent"
                android:layout_height="6dp"
                android:layout_marginTop="@dimen/text_small_margin"
                android:background="@color/gray_mercury"/>

            <android.support.v7.widget.RecyclerView
                android:id="@+id/tweets_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </LinearLayout>

    </android.support.v4.widget.NestedScrollView>

</LinearLayout>

 

Видим, что мы просто обернули всю нашу информацию в два новых контейнера: NestedSrollView и LinearLayout. Мы могли бы использовать только NestedScrollView, но у него есть одно ограничение: он должен содержать только один вложенный элемент. Именно поэтому нам пришлось обернуть всю нашу информацию в LinearlLayout. Всё это необходимо сделать, чтобы прокручивался весь наш экран, а не только список твитов. Теперь наш экран выглядит так, как нужно:

 

AwesomeRecyclerView.png

 

Осталось пару нюансов:

  • Наш список сейчас прокручивается не плавно.

  • Мы забыли добавить разделители между элементами списка.

Чтобы список прокручивался плавно, нам нужно запретить его внутреннее прокручивание, т.к. NestedScrollView берёт на себя эту функцию. Для этого можем использовать метод ViewCompat.setNestedScrollingEnabled(tweetsRecyclerView, false);.

Для того чтобы добавить разделители между элементами списка, необходимо добавить к RecyclerView стандартный ItemDecoration. Именно так и осуществляется добавление разделителей в список.
Выглядит вызов так: tweetsRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));

После добавления этих изменений код выглядит так:

 

UserInfoActivity.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public class UserInfoActivity extends AppCompatActivity {

    // Остальной код выше не изменился

    private void initRecyclerView() {
        tweetsRecyclerView = findViewById(R.id.tweets_recycler_view);

        ViewCompat.setNestedScrollingEnabled(tweetsRecyclerView, false);
        tweetsRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));

        tweetsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        tweetAdapter = new TweetAdapter();
        tweetsRecyclerView.setAdapter(tweetAdapter);
    }

    // Остальной код ниже не изменился
}

 

Видим, что разделители между элементами действительно добавились, и список начал прокручиваться плавно:

 

ListDivider.png

 

Полный листинг кода:

 

UserInfoActivity.java

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package colibri.dev.com.colibritweet.activity;

import java.io.IOException;
import java.util.Collection;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;

import org.json.JSONException;

import colibri.dev.com.colibritweet.R;
import colibri.dev.com.colibritweet.adapter.TweetAdapter;
import colibri.dev.com.colibritweet.network.HttpClient;
import colibri.dev.com.colibritweet.pojo.Tweet;
import colibri.dev.com.colibritweet.pojo.User;

public class UserInfoActivity extends AppCompatActivity {
    private ImageView userImageView;
    private TextView nameTextView;
    private TextView nickTextView;
    private TextView descriptionTextView;
    private TextView locationTextView;
    private TextView followingCountTextView;
    private TextView followersCountTextView;

    private RecyclerView tweetsRecyclerView;
    private TweetAdapter tweetAdapter;
    private Toolbar toolbar;

    private HttpClient httpClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_info);

        long userId = getIntent().getLongExtra(AuthActivity.USER_ID, -1);

        userImageView = findViewById(R.id.user_image_view);
        nameTextView = findViewById(R.id.user_name_text_view);
        nickTextView = findViewById(R.id.user_nick_text_view);
        descriptionTextView = findViewById(R.id.user_description_text_view);
        locationTextView = findViewById(R.id.user_location_text_view);
        followingCountTextView = findViewById(R.id.following_count_text_view);
        followersCountTextView = findViewById(R.id.followers_count_text_view);


        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        initRecyclerView();
        httpClient = new HttpClient();

        loadUserInfo(userId);
        loadTweets(userId);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.user_info_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.action_search) {
            Intent intent = new Intent(this, SearchUsersActivity.class);
            startActivity(intent);
        }
        return true;
    }

    @SuppressLint("StaticFieldLeak")
    private void loadTweets(final Long userId) {
        new AsyncTask<Void, Void, Collection<Tweet>>() {

            @Override
            protected Collection<Tweet> doInBackground(Void... voids) {
                try {
                    return httpClient.readTweets(userId);
                } catch (IOException | JSONException e) {
                    e.printStackTrace();
                    return null;
                }
            }

            @Override
            protected void onPostExecute(Collection<Tweet> tweets) {
                tweetAdapter.setItems(tweets);

            }
        }.execute();
    }

    private void initRecyclerView() {
        tweetsRecyclerView = findViewById(R.id.tweets_recycler_view);
        ViewCompat.setNestedScrollingEnabled(tweetsRecyclerView, false);
        tweetsRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        tweetsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        tweetAdapter = new TweetAdapter();
        tweetsRecyclerView.setAdapter(tweetAdapter);
    }

    @SuppressLint("StaticFieldLeak")
    private void loadUserInfo(final Long userId) {
        new AsyncTask<Void, Void, User>() {

            @Override
            protected User doInBackground(Void... voids) {
                try {
                    return httpClient.readUserInfo(userId);
                } catch (IOException | JSONException e) {
                    e.printStackTrace();
                    return null;
                }
            }

            @Override
            protected void onPostExecute(User user) {
                displayUserInfo(user);
            }
        }.execute();
    }

    private void displayUserInfo(User user) {
        Picasso.with(this).load(user.getImageUrl()).into(userImageView);
        nameTextView.setText(user.getName());
        nickTextView.setText(user.getNick());
        descriptionTextView.setText(user.getDescription());
        locationTextView.setText(user.getLocation());

        String followingCount = String.valueOf(user.getFollowingCount());
        followingCountTextView.setText(followingCount);

        String followersCount = String.valueOf(user.getFollowersCount());
        followersCountTextView.setText(followersCount);
        getSupportActionBar().setTitle(user.getName());
    }
}

 

 

activity_user_info.xml

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        style="@style/Toolbar"/>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="8dp">

                <de.hdodenhof.circleimageview.CircleImageView
                    android:id="@+id/user_image_view"
                    android:layout_width="96dp"
                    android:layout_height="96dp"
                    android:src="@mipmap/ic_launcher"/>

                <TextView
                    android:id="@+id/user_name_text_view"
                    style="@style/TextView.Primary.Header"
                    android:layout_below="@id/user_image_view"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:text="Имя"/>

                <TextView
                    android:id="@+id/user_nick_text_view"
                    style="@style/TextView.Secondary"
                    android:layout_below="@id/user_name_text_view"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:text="Ник"/>

                <TextView
                    android:id="@+id/user_description_text_view"
                    style="@style/TextView.Primary"
                    android:layout_below="@id/user_nick_text_view"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:text="Описание"/>

                <TextView
                    android:id="@+id/user_location_icon_text_view"
                    style="@style/TextIcon"
                    android:layout_alignBaseline="@id/user_location_text_view"
                    android:layout_below="@id/user_description_text_view"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:text="@string/fa_map_marker"/>

                <TextView
                    android:id="@+id/user_location_text_view"
                    style="@style/TextView.Secondary"
                    android:layout_below="@id/user_description_text_view"
                    android:layout_marginStart="10dp"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:layout_toEndOf="@id/user_location_icon_text_view"
                    android:text="Местоположение"/>

                <TextView
                    android:id="@+id/following_count_text_view"
                    style="@style/TextView.Primary.Bold"
                    android:layout_below="@id/user_location_text_view"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:text="4"/>

                <TextView
                    android:id="@+id/following_text_view"
                    style="@style/TextView.Secondary"
                    android:layout_below="@id/user_location_text_view"
                    android:layout_marginStart="5dp"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:layout_toEndOf="@+id/following_count_text_view"
                    android:text="@string/following_hint"/>

                <TextView
                    android:id="@+id/followers_count_text_view"
                    style="@style/TextView.Primary.Bold"
                    android:layout_below="@id/user_location_text_view"
                    android:layout_marginStart="20dp"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:layout_toEndOf="@+id/following_text_view"
                    android:text="4"/>

                <TextView
                    android:id="@+id/followers_text_view"
                    style="@style/TextView.Secondary"
                    android:layout_below="@id/user_location_text_view"
                    android:layout_marginStart="10dp"
                    android:layout_marginTop="@dimen/text_small_margin"
                    android:layout_toEndOf="@+id/followers_count_text_view"
                    android:text="@string/followers_hint"/>

            </RelativeLayout>

            <View
                android:id="@+id/delimeter_view"
                android:layout_width="match_parent"
                android:layout_height="6dp"
                android:layout_marginTop="@dimen/text_small_margin"
                android:background="@color/gray_mercury"/>

            <android.support.v7.widget.RecyclerView
                android:id="@+id/tweets_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </LinearLayout>

    </android.support.v4.widget.NestedScrollView>

</LinearLayout>

 

Подведём итоги:

  • Мы исправили наш интерфейс. После этого наш экран стал выглядеть намного лучше.

Полезные материалы:

УВИДЕТЬ ВСЕ Добавить заметку
Вы
Добавить ваш комментарий
 

Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для продолжения работы с сайтом, вам необходимо принять использование cookie-файлов.

Я ознакомлен(а)