Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: RecyclerView Adapter

Пример классического создания адаптера RecyclerView
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
public class UserDialogRecyclerAdapter extends RecyclerView.Adapter<UserDialogRecyclerAdapter.ViewHolder> {
 
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView vBodyMSG;
        public ImageView vBodyImageView;
        public ViewHolder(View v) {
            super(v);
            vBodyMSG = (TextView) v.findViewById(R.id.user_dialog_textView);
            vBodyImageView = (ImageView) v.findViewById(R.id.user_dialog_ImageView);        }
}
    public UserDialogRecyclerAdapter(Context context, JSONArray istemsJson) {
        messJson = istemsJson;
        mContext = context;
        count = messJson.length();
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_dialog_user, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }
    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        //остальной код создания адаптеров....
Собственно вопрос.
Использую я этот код для диалога. и по классике сообщения от меня по левому краю, сообщения от оппонента по правому краю. То же самое и с аватаркой моей и оппонента (моя слева от текста, оппонента справа).
Пробовал играться с программным изменением Layouta но все превращается в кашу и прыгает в непонятном направлении.
Можно использовать 2 адаптера и если можно то как?


Ниже приведу пример как я "играюсь" с Лайаутом. Может тут что не так.

Java
1
2
3
4
5
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            if(postJson.getString("out").equals("1"))
                lp.gravity = Gravity.RIGHT;
            else {lp.gravity = Gravity.CENTER_VERTICAL;}
            holder.vLinerLayout.setLayoutParams(lp);
Ответ:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        List<Message> messages = new ArrayList<>();
        messages.add(new Message("in", "Что делаешь?"));
        messages.add(new Message("in", "Не молчи!!!"));
        messages.add(new Message("in", "ты где???????"));
        messages.add(new Message("out", "шо надо?"));
 
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv);
        recyclerView.setAdapter(new RvAdapter(messages));
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recyclerView.setHasFixedSize(true);
    }
}
пример адаптер, минимум кода
Кликните здесь для просмотра всего текста
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
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
import java.util.List;
 
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.Holder> {
 
    private final static int TYPE_IN = 42;
    private final static int TYPE_OUT = 43;
    private final List<Message> list;
 
    public RvAdapter(List<Message> list) {
        this.list = list;
    }
 
    @Override
    public int getItemCount() {
        return list == null ? 0 : list.size();
    }
 
    @Override
    public Holder onCreateViewHolder(ViewGroup parent, int type) {
        View v = LayoutInflater.from(parent.getContext()).inflate(type == TYPE_IN ? R.layout.in_item : R.layout.out_item, parent, false);
        return new Holder(v);
    }
 
    @Override
    public void onBindViewHolder(Holder holder, int pos) {
        final Message msg = list.get(pos);
        holder.textView.setText(msg.text);
    }
 
    @Override
    public int getItemViewType(int pos) {
        return list.get(pos).dir.equals("in") ? TYPE_IN : TYPE_OUT;
    }
 
    static class Holder extends RecyclerView.ViewHolder {
 
        TextView textView;
 
        public Holder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.msgTv);
        }
    }
}


разметки для in out айтемов, тоже пример
Кликните здесь для просмотра всего текста
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
<?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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
 
    <android.support.v7.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        app:cardCornerRadius="16dp">
 
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="8dp">
 
            <ImageView
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:src="@drawable/circle_in" />
 
            <TextView
                android:id="@+id/msgTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="16dp"
                android:layout_marginStart="16dp"/>
 
        </LinearLayout>
 
    </android.support.v7.widget.CardView>
 
</FrameLayout>

Кликните здесь для просмотра всего текста
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
<?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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
 
    <android.support.v7.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end"
        android:layout_margin="8dp"
        app:cardCornerRadius="16dp">
 
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="8dp">
 
            <TextView
                android:id="@+id/msgTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="16dp"
                android:layout_marginStart="16dp"/>
 
            <ImageView
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:src="@drawable/circle_out" />
 
        </LinearLayout>
 
    </android.support.v7.widget.CardView>
 
</FrameLayout>


моделька, пример
Java
1
2
3
4
5
6
7
8
9
10
public class Message {
 
    final String dir;
    final String text;
 
    public Message(String dir, String text) {
        this.dir = dir;
        this.text = text;
    }
}
Вопрос: Как изменить Textview из другого класса (класса адаптера RecyclerView)

У меня есть список RecyclerView тоесть этот файл Basket и файл что реализует cardwiew BasketAdapter. как мне изменить TextView allPrice из BasketAdapter (в нем событие происходит нажатии кнопки) и при етом событии я хотел бы изменить TextView allPrice из Basket. Вообщем код приложил там есть комментарий где его хочу использовать
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
 
public class Basket extends AppCompatActivity {
 
    DBHelper dbHelper;
    private List<Product> list;
    ImageView btnMinus, btnPlus;
    RecyclerView recyclerView;
    BasketAdapter myAdapter;
    TextView allPrice;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basket);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        btnMinus = (ImageView) findViewById(R.id.cart_minus_img);
        btnPlus = (ImageView) findViewById(R.id.cart_plus_img);
 
 
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
 
        allPrice = (TextView) findViewById(R.id.allPrice);
        allPrice.setText(Integer.toString(getAllPrice()));
        list = DB.query(this);
 
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);
        
        myAdapter = new BasketAdapter(list);
        recyclerView.setAdapter(myAdapter);
 
    }
}

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
public class BasketAdapter extends RecyclerView.Adapter<BasketAdapter.ViewHolder> {
    private static List<Product> list;
 
 
    public BasketAdapter(List<Product> list)
    {
        this.list = list;
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent1, int viewType) {
        Context context = parent1.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.basket_list_item,parent1,false);
        return new ViewHolder(view);
    }
 
 
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Product item = list.get(position);
        holder.imgmini.setImageResource(item.getResid());
        holder.textTitle.setText(item.getName());
 
        if(item.getCount() != 0)
          holder.textCount.setText(Integer.toString(item.getCount()));
 
        holder.textCost.setText(Integer.toString(item.getPrice()));
    }
 
    @Override
    public int getItemCount() {
        return list.size();
    }
    public static class ViewHolder extends RecyclerView.ViewHolder{
        ImageView imgmini;
        ImageView btnMinus, btnPlus;
        TextView textTitle;
        TextView textCount;
        TextView textCost;
        CardView cv;
        TextView allPrice;
        private final Context context;
        public ViewHolder(final View itemView)
        {
            super(itemView);
            final TextView cart;
 
            imgmini = (ImageView) itemView.findViewById(R.id.imgmini);
            textTitle = (TextView) itemView.findViewById(R.id.textTitle);
            textCount = (TextView) itemView.findViewById(R.id.cart_product_quantity_tv);
            textCost = (TextView) itemView.findViewById(R.id.textCost);
            btnMinus = (ImageView) itemView.findViewById(R.id.cart_minus_img);
            btnPlus = (ImageView) itemView.findViewById(R.id.cart_plus_img);
            cart = (TextView) itemView.findViewById(R.id.cart_product_quantity_tv);
            cv = (CardView) itemView.findViewById(R.id.cv1);
 
 
 
            context = itemView.getContext();
 
            View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
 
                    String text = cart.getText().toString();
                    ContentValues cv = new ContentValues();
                    cv.put(DBHelper.KEY_COUNT,1);
                    int count = Integer.parseInt(text);
                    switch (v.getId()) {
                        case R.id.cart_minus_img:
                            if(count > 1){
                                count-- ;
 
                                DB.update(context,list.get(getLayoutPosition()).getId() ,cv);
                               //вот тот надо бы как то достать     TextView allPrice; из Basket и allPrice.setText(Integer.toString(DB.getAllPrice(context)));
                               //вот как сделать хз 
 
                            }
                            else if (count == 1)
                                list.remove(0);
                            break;
                        case  R.id.cart_plus_img:
                            count++;
                            break;
 
                    }
                    cart.setText(Integer.toString(count));
                }
            };
 
            btnMinus.setOnClickListener(onClickListener);
            btnPlus.setOnClickListener(onClickListener);
            
        }
 
    }
 
}
Добавлено через 5 часов 8 минут
что некто не знает как переменную TextView c другого класса обработать в данном случае?
Ответ: что тут непонятного?
Java
1
myAdapter = new BasketAdapter(list, allPrice);
и в адаптере принимаешь ссылку на эту текствью и делаешь там с нем что угодно
Вопрос: NullPointerException в адаптере RecyclerView

Здравствуйте уважаемые форумчане!
Столкнулся с такой проблемой, в RecyclerView создаю адаптер для добавления карточек, в карточке, в левом верхнем углу находится картинка, при нажатии на которую карточка увеличивается в размерах и в ней меняется FrameLayout.
Вот все исходники:
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
package com.example.max.recyclerviewmenu;
 
/**
 * Created by Max on 10.12.2016.
 */
 
public class CardMenu {
    int mImage;
    String mName;
    String mAmount;
    String mData;
    String mTime;
    String mAdd;
    String mDel;
 
    CardMenu(int image, String name, String amount, String data, String time, String add, String del) {
        mImage = image;
        mName = name;
        mAmount = amount;
        mData = data;
        mTime = time;
        mAdd = add;
        mDel = del;
    }
}
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
package com.example.max.recyclerviewmenu;
 
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.Scene;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecyclerAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
 
    private List<CardMenu> card_menu;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        initializeData();
 
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_menu);
        mRecyclerView.setHasFixedSize(true);
 
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
 
        mAdapter = new RecyclerAdapter(card_menu);
        mRecyclerView.setAdapter(mAdapter);
    }
 
    private void initializeData() {
        card_menu = new ArrayList<>();
 
        for (int i = 0; i < 100; i++) {
            card_menu.add(new CardMenu((i % 2) == 0 ? R.drawable.ic_tartuga1 :R.drawable.ic_tartuga2,
                    "Name", "Amount", "Data", "Time", "Add", "Del"));
        }
    }
}
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
package com.example.max.recyclerviewmenu;
 
import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.Scene;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
 
import java.util.List;
 
/**
 * Created by Max on 10.12.2016.
 */
 
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
    List<CardMenu> card_menu;
    Scene scene1;
    Scene scene2;
    ViewGroup parent;
    ViewGroup view_scene1;
    ViewGroup view_scene2;
 
    public static class ViewHolder extends RecyclerView.ViewHolder {
        CardView cv;
        public ImageView imageView;
        public TextView mName;
        public TextView mAmount;
        public TextView mData;
        public TextView mTime;
        public TextView mAdd;
        public TextView mDel;
 
        public ViewHolder(View v) {
            super(v);
            InitializeScene1(v);
        }
 
        void InitializeScene1(View v) {
            cv        = (CardView)  v.findViewById(R.id.card_view);
            imageView = (ImageView) v.findViewById(R.id.image_view);
            mName     = (TextView)  v.findViewById(R.id.name);
            mAmount   = (TextView)  v.findViewById(R.id.amount);
            mAdd      = (TextView)  v.findViewById(R.id.add);
            mDel      = (TextView)  v.findViewById(R.id.del);
        }
 
        void InitializeScene2(View v) {
            cv        = (CardView)  v.findViewById(R.id.card_view);
            imageView = (ImageView) v.findViewById(R.id.image_view);
            mName     = (TextView)  v.findViewById(R.id.name);
            mAmount   = (TextView)  v.findViewById(R.id.amount);
            mData     = (TextView)  v.findViewById(R.id.data);
            mTime     = (TextView)  v.findViewById(R.id.time);
            mAdd      = (TextView)  v.findViewById(R.id.add);
            mDel      = (TextView)  v.findViewById(R.id.del);
        }
    }
 
    public RecyclerAdapter(List<CardMenu> card_menu) {
        this.card_menu = card_menu;
    }
 
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.d("my", "onCreateViewHolder");
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recycler_view_menu_item, parent, false);
 
        this.parent = parent;
 
        scene1 = Scene.getSceneForLayout(parent, R.layout.scene1, parent.getContext());
        scene2 = Scene.getSceneForLayout(parent, R.layout.scene2, parent.getContext());
 
        ViewHolder vh = new ViewHolder(v);
 
        return vh;
    }
 
    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        Log.d("my", "onBindViewHolder");
        Log.d("my", "position = " + position);
        holder.imageView.setImageResource(card_menu.get(position).mImage);
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("my", "onClick!");
                TransitionSet set = new TransitionSet();
                set.addTransition(new Fade());
                set.addTransition(new ChangeBounds());
                set.setOrdering(TransitionSet.ORDERING_TOGETHER);
                set.setDuration(500);
                set.setInterpolator(new AccelerateInterpolator());
                TransitionManager.go(scene2, set);
                Log.d("my", "endClick!");
 
                View v = LayoutInflater.from(scene2.getSceneRoot().getContext())
                        .inflate(R.layout.recycler_view_menu_item, scene2.getSceneRoot(), false);
 
                holder.InitializeScene2(v);
 
                holder.imageView.setImageResource(card_menu.get(position).mImage);
                holder.mName.setText(card_menu.get(position).mName);
                holder.mAmount.setText(card_menu.get(position).mAmount);
                holder.mData.setText(card_menu.get(position).mData);
                holder.mTime.setText(card_menu.get(position).mTime);
                holder.mAdd.setText(card_menu.get(position).mAdd);
                holder.mDel.setText(card_menu.get(position).mDel);
            }
        });
        holder.mName.setText(card_menu.get(position).mName);
        holder.mAmount.setText(card_menu.get(position).mAmount);
        holder.mAdd.setText(card_menu.get(position).mAdd);
        holder.mDel.setText(card_menu.get(position).mDel);
    }
 
    @Override
    public int getItemCount() {
        return card_menu.size();
    }
 
    public Scene getScene1() {
        return  scene1;
    }
 
    public Scene getScene2() {
        return scene2;
    }
}
Ошибка происходит в функции:
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
holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("my", "onClick!");
                TransitionSet set = new TransitionSet();
                set.addTransition(new Fade());
                set.addTransition(new ChangeBounds());
                set.setOrdering(TransitionSet.ORDERING_TOGETHER);
                set.setDuration(500);
                set.setInterpolator(new AccelerateInterpolator());
                TransitionManager.go(scene2, set);
                Log.d("my", "endClick!");
 
                View v = LayoutInflater.from(scene2.getSceneRoot().getContext())
                        .inflate(R.layout.recycler_view_menu_item, scene2.getSceneRoot(), false);
 
                holder.InitializeScene2(v);
 
                holder.imageView.setImageResource(card_menu.get(position).mImage);
                holder.mName.setText(card_menu.get(position).mName);
                holder.mAmount.setText(card_menu.get(position).mAmount);
                holder.mData.setText(card_menu.get(position).mData);
                holder.mTime.setText(card_menu.get(position).mTime);
                holder.mAdd.setText(card_menu.get(position).mAdd);
                holder.mDel.setText(card_menu.get(position).mDel);
            }
        });
Ошибка:
Java
1
2
Process: com.example.max.recyclerviewmenu, PID: 10574
                                                                                  java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
Уважаемые гуру программирования под Android, прошу помочь, а то мне нужно скоро вставить этот код в проект, а он не работает.
Ответ: во-первых это не весь лог ошибки
во-вторых где метод shouldIgnore() ?? его вообще нет в коде
Вопрос: Заполнить RecyclerView из Cursor

Ребят подскажите плз, есть ли способы закинуть данные с бд типа Cursor в список ResyclerView? Или нужно обязательно переводить данные в ArrayList<>?
Если нужно переносить, то где это осуществить будет правильно в ХелпереБазы (создать к примеру метод в котором осуществляется конвертация) или в самом адаптере RecyclerView?
Спасибо.
Ответ: asttoxa, теоретически адаптер не должен знать, откуда ему прилетают данные и он тем более не должен их парсить из курсора в объекты. должна быть прослойка из класса, который получает от кого-то запрос на данные (activity|fragment), идет в БД, извлекает данные, парсит в объекты и отдает просящему по callback либо синхронно.
Упрощенный пример такого класса, может содержать ситнаксические ошибки ибо обрезал лишнее.
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
public class DiskDataSource {
    private SQLiteDatabase database;
    private SQLiteHelper sqliteHelper;
 
    public DiskDataSource(Context context){
        sqliteHelper = new SQLiteHelper(context);
    }
 
    public void open(){
        database = sqliteHelper.getWritableDatabase();
    }
 
    public void close() {
        sqliteHelper.close();
    }
 
    @NonNull
    public List<Weather> selectWeatherItemsBy(int cityId, int limit){
        String table = DBConst.TABLE.WEATHERS;
        String selection = DBConst.TABLE.WEATHERS + "." + DBConst.WEATHER_COLUMN.CITY_ID + " = ?"
        String[] selectionArgs = {String.valueOf(cityId)};
        String orderBy = DBConst.TABLE.WEATHERS + "." + DBConst.WEATHER_COLUMN.DATE + " ASC";
        String qlimit = limit <= 0 ? null : String.valueOf(limit);
        Cursor cursor = database.query(table, columns, selection, selectionArgs, null, null, orderBy, qlimit);
        List<Weather> results = new ArrayList<>();
        if(cursor!=null){
            if(cursor.moveToFirst()){
                while (!cursor.isAfterLast()) {
                    Weather item = WeatherMapper.transform(cursor); //в методе парсим поля курсора в объект
                    results.add(item);
                    cursor.moveToNext();
                }
            }
            cursor.close();
        }
        return results;
    }
}
Вопрос: Адаптер обновляется автоматически

Я устанавливаю пустой список в адаптер Recyclerview а потом в onStart() просто читаю элементы из бызы данных в AsynkTask и адаптер не обновляю, но элементы в него все равно добавляются.
код активити
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
155
156
public class MainActivity extends AppCompatActivity {
    //private List<Movie> movieList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MoviesAdapter mAdapter;
    private ImageButton btnAddSite;
    private ProgressDialog pDialog;
    private ArrayList<HashMap<String, String>> rssFeedList;
    private String[] sqliteIds;
    public static String TAG_ID = "id";
    public static String TAG_TITLE = "title";
    public static String TAG_LINK = "link";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       /* Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);*/
 
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        btnAddSite = (ImageButton) findViewById(R.id.btnAddSite);
        rssFeedList = new ArrayList<HashMap<String, String>>();
        mAdapter = new MoviesAdapter( rssFeedList);
        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);
 
        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {
               // Movie movie = movieList.get(position);
                //Toast.makeText(getApplicationContext(), movie.getTitle() + " is selected!", Toast.LENGTH_SHORT).show();
 
            /*    String sqlite_id = ((TextView) view.findViewById(R.id.sqlite_id)).getText().toString();
                // Starting new intent
                Intent in = new Intent(getApplicationContext(), ListRSSItemsActivity.class);
                // passing sqlite row id
                in.putExtra(TAG_ID, sqlite_id);
                startActivity(in);*/
            }
 
            @Override
            public void onLongClick(View view, int position) {
 
            }
        }));
 
        btnAddSite.setOnClickListener(new View.OnClickListener() {
 
            public void onClick(View v) {
                Intent i = new Intent(getApplicationContext(), AddNewSiteActivity.class);
                // starting new activity and expecting some response back
                // depending on the result will decide whether new website is
                // added to SQLite database or not
                startActivityForResult(i, 100);
            }
        });
 
        prepareMovieData();
    }
 
    private void prepareMovieData() {
 
    }
 
    @Override
    protected void onStart() {
        super.onStart();
        new loadStoreSites().execute();
    }
 
 
    class loadStoreSites extends AsyncTask<String, String, String> {
 
        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(
                    MainActivity.this);
            pDialog.setMessage("Loading websites ...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }
 
        /**
         * getting all stored website from SQLite
         * */
        @Override
        protected String doInBackground(String... args) {
            // updating UI from Background Thread
            //runOnUiThread(new Runnable() {
               // public void run() {
                    RSSDatabaseHandler rssDb = new RSSDatabaseHandler(
                            getApplicationContext());
 
                    // listing all websites from SQLite
                    List<WebSite> siteList = rssDb.getAllSites();
 
                    sqliteIds = new String[siteList.size()];
 
                    // loop through each website
                    for (int i = 0; i < siteList.size(); i++) {
 
                        WebSite s = siteList.get(i);
 
                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();
 
                        // adding each child node to HashMap key => value
                        map.put(TAG_ID, s.getId().toString());
                        map.put(TAG_TITLE, s.getTitle());
                        map.put(TAG_LINK, s.getLink());
 
                        // adding HashList to ArrayList
                        rssFeedList.add(map);
 
                        // add sqlite id to array
                        // used when deleting a website from sqlite
                        sqliteIds[i] = s.getId().toString();
                    }
                    /**
                     * Updating list view with websites
                     * */
 
                     /*adapter = new SimpleAdapter(
                            MainActivity.this,
                            rssFeedList, R.layout.site_list_row,
                            new String[] { TAG_ID, TAG_TITLE, TAG_LINK },
                            new int[] { R.id.sqlite_id, R.id.title, R.id.link });
                    // updating listview
                    recyclerView.setAdapter(adapter); */
                    //recyclerView.setAdapter(mAdapter);
                    //registerForContextMenu(recyclerView);
              //  }
            //});
            return null;
        }
 
        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String args) {
            // dismiss the dialog after getting all products
            //mAdapter.update(rssFeedList);
            pDialog.dismiss();
        }
 
    }
}
Код адаптера

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
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {
 
    public static String TAG_ID = "id";
    public static String TAG_TITLE = "title";
    public static String TAG_LINK = "link";
    private List<HashMap<String, String>> moviesList = new ArrayList<HashMap<String, String>>();
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView sqlite_id, title, link;
 
        public MyViewHolder(View view) {
            super(view);
            sqlite_id = (TextView) view.findViewById(R.id.sqlite_id);
            title = (TextView) view.findViewById(R.id.title);
            link = (TextView) view.findViewById(R.id.link);
        }
    }
 
 
    public MoviesAdapter(List<HashMap<String, String>> moviesList) {
        this.moviesList = moviesList;
    }
 
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.site_list_row, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    public void update(List<HashMap<String, String>> items) {
        this.moviesList.clear();
        this.moviesList.addAll(items);
        notifyDataSetChanged();
    }
 
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        /*Movie movie = moviesList.get(position);
        holder.title.setText(movie.getTitle());
        holder.genre.setText(movie.getGenre());
        holder.year.setText(movie.getYear());*/
        WebSite s = new WebSite();
        holder.sqlite_id.setText(moviesList.get(position).get(TAG_ID));
        holder.title.setText(moviesList.get(position).get(TAG_TITLE));
        holder.link.setText(moviesList.get(position).get(TAG_LINK));
    }
 
    @Override
    public int getItemCount() {
        return moviesList.size();
    }
}
Ответ: ExpandableListView

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

Вопрос может нубский, но нужен ответ

Есть необходимость сделать multi selectable RecyclerView адаптер.

Сделал по примеру

но тут для выхода из режима selectable нужно нажимать на кнопочку в actionMenu(и вообще по примеру, нужно выводить actionMenu, мне он не нужен).

Вопрос:
1. Как реализовать (или переделать этот пример) так чтобы долгое нажатие начинает выделение, а если убираем выделение со всех элементов то выходим из режима selectable.
2. при однократном клике выполнять какой то код (в этом примере как я понял если вешать клик листенер то перестает работать selectable) - (может неправильно понял)

Добавлено через 52 минуты
Не знаю как по умному это делают разработчики.

Я сделал так(дополнил пример из хабра):

В адаптере
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
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder holder, boolean isSelected) {
        ((CustomViewHolder) holder).timingCheckable.setChecked(isSelected);
 
        if (getSelectionHelper().isSelectable() && getSelectionHelper().getSelectedItemsCount() == 0){
            getSelectionHelper().setSelectable(false);
        }
    }
 
public void deleteSelectsItems(){
 
        if (getItemCount() != 0){
            Iterator iterator = dataFiltered.iterator();
            int i = 0;
            while (iterator.hasNext()){
                PzhdWorkSchedule data = (PzhdWorkSchedule) iterator.next();
                if (getSelectionHelper().isItemSelected(i)){
                    iterator.remove();
                }
                i++;
            }
        }
        getSelectionHelper().setSelectable(false);
        notifyDataSetChanged();
    }
Ответ: что значит замусоривать модель данных...
эта модель как раз и предназначается для правильного показа айтемов

в такой ситуации или когда надо добавить каких-то красивостей при показе я лично вообще делаю отдельный класс, типа wrapper для модели данных и уже там добавляю все поля из которых потом холдеры будут читать значения и показывать айтемы как требуется

дополнительного кода никакого вообще нет, просто еще один класс wrapper
на котлине это вообще одна строка, типа такого

data class Wrapper(val model: YourClass, val isSelected : Boolean = false) ну и еще любые поля какие надо там под задачу
и все - в адаптер скармливаем не List<YourClass>, а List<Wrapper>

в итоге получаем полный контроль над показом холдеров, хоть в радугу их можно красить через одного, главное что бы у враппера были все нужные поля - флаги
Вопрос: Как настроить RecyclerView ?

При загрузке с сети информации в RecyclerView помещается по 100 элементов, сделал так что при достижении конца списка загружается еще 100 и так далее.

Но при добавлении новых записей список автоматично сбрасывается на начало списка. А мне нужно чтоб он оставался на месте, и записи просто добавлялись, но ничего со списком не происходило!

Вопрос:
Как сделать так, чтоб RecyclerView открывался в заданной позиции (ну или при изменении не бежал в начало )?
Ответ:
Сообщение от prokopov
Как сделать так, чтоб RecyclerView открывался в заданной позиции (ну или при изменении не бежал в начало )?
так он и не бежит в начало, скорее всего вы вместо того что бы добавить данные и обновить адаптер, создаете новый адаптер
Вопрос: RecyclerView фиксированый height

Мне кажется много кто встречался с данной проблемой.
у меня есть корзина, в ней RecyclerView с фиксированой высотой. (что бы там 3 карточки масимум вмещались)
под ним находится цена. И вот когда карточек не 3 а одна, из за того что размер RecyclerView фиксированый цена так и висит на том же месте(далеко от карточки,не очень естетично)
- wrap_content решает данную ситуацию, но к сожелению нету такого свойства как maxheight который бы ограчинил высоту(мне же только надо максимум 3 показывать карточки,и включать прокрутку если больше)
на картинке показано как выглядит 1карточка(совсем неочень)
Ответ: господи, та шо там сложного
пример активити
Кликните здесь для просмотра всего текста
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
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
 
public class MainActivity extends AppCompatActivity implements View.OnLayoutChangeListener {
 
    private static final int MAX_ITEMS = 3;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
        rv.setAdapter(new CustomAdapter());
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.addOnLayoutChangeListener(this);
    }
 
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        final RecyclerView rv = (RecyclerView) v;
        if (rv.getChildCount() > 0) {
            final ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) rv.getLayoutParams();
            final Rect r = new Rect();
            rv.getDecoratedBoundsWithMargins(rv.getChildAt(0), r);
            lp.height = r.height() * MAX_ITEMS;
        }
    }
}

разметка активити, пример тоже
Кликните здесь для просмотра всего текста
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
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:subtitle="Subtitle"
        app:title="Title" />
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar" />
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_below="@+id/rv"
        android:layout_marginEnd="16dp"
        android:layout_marginStart="16dp"
        android:text="Цена: 100 000$" />
 
    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_margin="16dp"
        app:fabSize="auto" />
 
</RelativeLayout>

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

Добрый день!

Есть Activity с ViewPager из 2 страниц (фрагмент один). В фрагмент, в зависимости от номера страницы, вставляется список RecyclerView, в каждом элементе которого есть изображение. Удерживая изображение можно менять порядок расположения элементов.

В меню есть пункт "Delete". Задумка такая: по нажатию Delete из меню, изображения для перетаскивания элементов заменяются изображениями для удаления (крестик, например). С какой стороны подходить к решению данного вопроса пока не очень понимаю.

1) возможно ли динамически менять адаптер? Тогда через него загружать разметку с кнопкой удаления.
2) разместить на макете сразу оба изображения и одно из них изначально скрыть, а потом менять их видимость. Но тут не очень понимаю как ее менять, ведь обработка нажатий на кнопки меню в Activity, а адаптер во фрагменте.

В общем заранее благодарен за возможные идеи
Ответ:

Не по теме:

ну я просто подтвердил слова :)

Сообщение от Hugonavy
Или слишком тупая?
я щас не конкретно про эту тему, но
не буду скрывать, что меня тригерит каждый раз когда приходится людям объяснять что recyclerview чуть ли не самый универсальный виджет
на нем практически все что угодно можно вымостить, надо просто немного времени потратить на изучение

Вопрос: Как развернуть RecyclerView

Делаю свой месседжер и столкнулся с проблемой, как развернуть RecyclerView (на подобии сообщений в ВК)
у меня есть идея, вставлять элементы на 0е место, но не могу найти как это сделать.
Ответ:
Сообщение от kair32
вставлять элементы на 0е место
0-е это сверху) тебе , если я правельно понял нужно снизу/ по этому его нужно развернутЬ это делается так:
XML
1
2
3
4
5
<android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recyclerView" 
        android.support.v7.recyclerview:stackFromEnd ="true"/>
или так
Java
1
2
3
mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
далее, чтоб добавить в нужную позицию, просто делаем так
Java
1
2
mArrayList.add(position, item);
notifyItemInserted(position);
где mArrayList это массив в адаптере

Добавлено через 48 секунд
и да. мысль изложена кривовато