Cambiar el diseño de la cuadrícula de lista de Android RecyclerView

prefacio

No hablaré más sobre el uso de RecyclerView. Los próximos artículos hablarán principalmente sobre las funciones prácticas de RecyclerView, incluido el cambio de cuadrícula de lista, el efecto de techo, el efecto de diseño múltiple, etc. El artículo de hoy implementará la lista. La forma de cambiar la red del palacio es la siguiente:


1. Fuente de datos

Los datos provienen de la API diaria de Zhihu, que se solicita mediante la combinación okhttp + retrofit. La solicitud de red no se vuelve a encapsular, simplemente solicita la fuente de datos. Los usuarios que la necesiten pueden realizar modificaciones de encapsulación por sí mismos.

2. Pasos de uso

1. Importar la biblioteca

  //万能适配器
  implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'
  //卡片布局
  implementation 'androidx.cardview:cardview:1.0.0'
  //图片加载
  implementation 'com.github.bumptech.glide:glide:4.9.0'
  //json解析
  implementation 'com.alibaba:fastjson:1.2.61'
  //标题栏
  implementation 'com.github.goweii:ActionBarEx:3.2.2'
  // 只引入ActionBarEx
  implementation 'com.github.goweii.ActionBarEx:actionbarex:3.2.2'
  // 引入ActionBarCommon/Search/Super,依赖于ActionBarEx
  implementation 'com.github.goweii.ActionBarEx:actionbarex-common:3.2.2'

2. Obtener datos

 Utilice la siguiente URL para realizar solicitudes de datos: Los métodos HTTP utilizados por la API son todos GET

https://news-at.zhihu.com/api/3/news/hot

Ejemplo de respuesta:

{
    "recent": [
        {
            "news_id": 3748552,
            "thumbnail": "http://p3.zhimg.com/67/6a/676a8337efec71a100eea6130482091b.jpg",
            "title": "长得漂亮能力出众性格单纯的姑娘为什么会没有男朋友?",
            "url": "http://daily.zhihu.com/api/2/news/3748552"
        }
    ]
}

Genere la clase de entidad NewsListBean según la instancia e implemente la interfaz de intercambio en serie Serializable

public class NewsListBean implements Serializable {

    private String date;
    private List<Recent> recent;


    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public List<Recent> getRecent() {
        return recent;
    }

    public void setRecent(List<Recent> recent) {
        this.recent = recent;
    }

    public static class Recent implements Serializable {
        private String news_id;
        private String thumbnail;
        private String title;
        private String url;

        public String getNews_id() {
            return news_id;
        }

        public void setNews_id(String news_id) {
            this.news_id = news_id;
        }

        public String getThumbnail() {
            return thumbnail;
        }

        public void setThumbnail(String thumbnail) {
            this.thumbnail = thumbnail;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }
    }
}

Escriba una clase de interfaz para administrar la API, que se puede colocar en una carpeta separada

public interface ApiUrl {

    @GET("/api/4/news/hot")
    Call<NewsListBean> getPic();

}

3. Código principal

1 actividad_principal.xml

Aquí, la biblioteca de terceros ActionBarEx se usa   para implementar la barra de título inmersiva y la ProgressBar del sistema se usa para implementar el cuadro de carga de solicitudes.

<?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">

    <per.goweii.actionbarex.ActionBarEx
        android:id="@+id/abc_main_return"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#14a4fb"
        app:ab_autoImmersion="false"
        app:ab_bottomLineColor="#f3f3f3"
        app:ab_bottomLineHeight="0dp"
        app:ab_statusBarColor="#00000000"
        app:ab_statusBarMode="dark"
        app:ab_statusBarVisible="true"
        app:ab_titleBarHeight="50dp"
        app:ab_titleBarLayout="@layout/top" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/zh_lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/abc_main_return" />

    <ProgressBar
        android:id="@+id/progressbar"
        style="@style/Base.Widget.AppCompat.ProgressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:visibility="gone" />
</RelativeLayout>

2 zh_item_layout.xml

Subdiseño de lista, utilizando el diseño de tarjeta CardView

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/zh_card_View"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/dp_10"
    android:layout_marginTop="10dp"
    android:layout_marginRight="@dimen/dp_10"
    android:layout_marginBottom="@dimen/dp_10"
    app:cardBackgroundColor="#ffffff"
    app:cardCornerRadius="10dp"
    app:cardElevation="10dp"
    app:cardPreventCornerOverlap="true"
    app:cardUseCompatPadding="false">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="120dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/transparent">

            <ImageView
                android:id="@+id/news_image"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:layout_centerVertical="true"
                android:layout_margin="10dp"
                android:elevation="2dp"
                android:scaleType="fitXY" />

            <TextView
                android:id="@+id/news_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginStart="10dp"
                android:layout_marginTop="10dp"
                android:layout_marginEnd="10dp"
                android:layout_toEndOf="@id/news_image"
                android:ellipsize="end"
                android:maxEms="15"
                android:singleLine="true"
                android:textColor="@color/black"
                android:textSize="20sp" />
        </RelativeLayout>
    </RelativeLayout>


</androidx.cardview.widget.CardView>

3 zh_grid__item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/zh_card_View"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:layout_marginLeft="@dimen/dp_10"
    android:layout_marginTop="10dp"
    android:layout_marginRight="@dimen/dp_10"
    android:layout_marginBottom="@dimen/dp_10"
    app:cardBackgroundColor="#ffffff"
    app:cardCornerRadius="10dp"
    app:cardElevation="10dp"
    app:cardPreventCornerOverlap="true"
    app:cardUseCompatPadding="false">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/transparent"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="@dimen/dp_10">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="3">

            <ImageView
                android:id="@+id/news_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center">

            <TextView
                android:id="@+id/news_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:maxEms="8"
                android:singleLine="true"
                android:textColor="@color/black"
                android:textSize="20sp" />

        </LinearLayout>


    </LinearLayout>


</androidx.cardview.widget.CardView>

4 Adaptador NewsListAdapter

public class NewsListAdapter extends BaseQuickAdapter<NewsListBean.Recent, BaseViewHolder> {

    public NewsListAdapter(int layoutResId, @Nullable List<NewsListBean.Recent> data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(@NonNull BaseViewHolder helper, NewsListBean.Recent item) {
        helper.setText(R.id.news_title, item.getTitle());
        String img = item.getThumbnail();
        ImageView newsImage = helper.getView(R.id.news_image);
        Glide.with(mContext).
                asBitmap().
                load(img).
                diskCacheStrategy(DiskCacheStrategy.ALL).
                into(newsImage);
        helper.addOnClickListener(R.id.zh_card_View);
    }


}

5 clase base BaseActivity

public abstract class BaseActivity extends AppCompatActivity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        Window window = getWindow();
        // 5.0以上系统状态栏透明
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                // 全屏显示,隐藏状态栏和导航栏,拉出状态栏和导航栏显示一会儿后消失。
                window.getDecorView().setSystemUiVisibility(
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                // | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                                // | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                // | View.SYSTEM_UI_FLAG_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            } else {
                // 全屏显示,隐藏状态栏
                window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
            }
        }
        //预防软键盘挡住输入框
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        //禁止横屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        super.onCreate(savedInstanceState);

    }

  
}

6 Código principal de MainActivity 

Aquí utilizamos principalmente un valor booleano isGrid para determinar si cambiar de estado para cargar diferentes diseños y el administrador de diseño para lograr el efecto real.

public class MainActivity extends BaseActivity {

    private RecyclerView zhLv;
    private ProgressBar proBar;
    private NewsListAdapter adapter;


    private List<NewsListBean.Recent> mList = new ArrayList<>();


    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private ImageView menuBtn;
    private LinearLayoutManager layoutManager;
    private ImageView btnImg;
    private LinearLayout backLayoput;

    public static void verifyStoragePermissions(Activity activity) {
        int permission = ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE);
        }
    }

    private boolean isGrid = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        verifyStoragePermissions(MainActivity.this);
        initView();
        initData();

        menuBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switchLayout();
            }
        });
    }


    private void switchLayout() {

        if (isGrid) {
            layoutManager = new LinearLayoutManager(this);
            adapter = new NewsListAdapter(R.layout.zh_item_layout, mList);
            zhLv.setAdapter(adapter);
        } else {
            layoutManager = new GridLayoutManager(this, 2);
            adapter = new NewsListAdapter(R.layout.zh_grid__item_layout, mList);
            zhLv.setAdapter(adapter);
        }
        zhLv.setLayoutManager(layoutManager);
        isGrid = !isGrid;
    }

    private void initView() {
        zhLv = findViewById(R.id.zh_lv);
        proBar = findViewById(R.id.progressbar);
        menuBtn = findViewById(R.id.btn_main_menu);
        btnImg = findViewById(R.id.btn_main_menu);
        backLayoput = findViewById(R.id.btn_back_layout);
        backLayoput.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        layoutManager = new LinearLayoutManager(MainActivity.this);
        zhLv.setLayoutManager(layoutManager);
        adapter = new NewsListAdapter(R.layout.zh_item_layout, mList);
        zhLv.setAdapter(adapter);
    }

    private void initData() {
        proBar.setVisibility(View.VISIBLE);
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://news-at.zhihu.com/")
                //设置数据解析器
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ApiUrl apiUrl = retrofit.create(ApiUrl.class);
        Call<NewsListBean> call = apiUrl.getPic();
        call.enqueue(new Callback<NewsListBean>() {
                         @Override
                         public void onResponse(Call<NewsListBean> call, Response<NewsListBean> response) {

                             List<NewsListBean.Recent> recent = response.body().getRecent();
                             if (response.body() != null && recent.size() > 0) {
                                 try {
                                     mList.addAll(recent);
                                     adapter.setNewData(mList);
                                     proBar.setVisibility(View.GONE);
                                 } catch (Exception e) {
                                     String message = e.getMessage();
                                     e.printStackTrace();
                                 }
                             }
                         }

                         @Override
                         public void onFailure(Call<NewsListBean> call, Throwable t) {
                             Log.e("mmm", "errow " + t.getMessage());
                         }
                     }
        );


    }


}

Resumir

Se completa una función pequeña y muy práctica. El próximo artículo continuará implementando el efecto techo de RecyclerView. En el futuro, se agregarán funciones como el almacenamiento en caché local de listas. La demostración se adjunta al final de esta serie de artículos. También te puede gustar y coleccionarlo~

Las colinas verdes no cambiarán, el agua verde fluirá para siempre, nos vemos en los ríos y lagos ~

Supongo que te gusta

Origin blog.csdn.net/X_sunmmer/article/details/131245912
Recomendado
Clasificación