热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SwipeRefreshLayout、RecyclerView和CardView组合使用

前面我们介绍了AlertDialog和几个常用的Dialog,ProgressDialog进度条提示框、DatePickerDialog日期选择对话框和TimePic

 前面我们介绍了AlertDialog和几个常用的Dialog,ProgressDialog进度条提示框、DatePickerDialog日期选择对话框和TimePickerDialog时间选择对话框。这一节我们介绍几个新的API控件SwipeRefreshLayout、RecyclerView和CardView,这几个API控件都是google在Android5.0推出的。下面我们来学习一下这几个新的控件:

SwiperefreshLayout

  SwiperefreshLayout是Android提供的一个下拉刷新的布局,继承自ViewGroup,在support v4兼容包下,想要使用必须把你的support library的版本升级到19.1。相信很多Android开发者都对ActionBarPullToRefresh这个框架比较熟悉。SwiperefreshLayout的推出,对于我们实现下拉刷新就变得非常简单了。

下面是SwiperefreshLayout的常用方法:

  • setOnRefreshListener(OnRefreshListener): 为布局添加一个Listener

  • setRefreshing(boolean): 设置是否处于刷新状态

  • isRefreshing(): 检查是否处于刷新状态

  • setColorScheme(): 设置进度条的颜色主题,最多能设置四种

  • setProgressBackgroundColorSchemeResource(): 设置进度条背景颜色

使用的话就直接在XML文件中使用即可,例如:



这个一个布局容器,我们可以在其上添加其他的控件。附上SwiperefreshLayout的国内镜像API

RecyclerView

  RecyclerView是Android5.0之后推出的一个新的控件,这是一个强大的滑动组件,比ListView拥有更多的功能。官方介绍RecyclerView是ListView的升级版,RecyclerView有如下的优点:

  • RecylerView封装了viewholder的回收复用,也就是说是RecyclerView是面向ViewHolder编程而不是View

  • RecyclerView高度解耦,非常灵活。RecyclerView不仅可以像ListView一样显示列表视图,还可以显示网格视图等。只要你传入不同的LayoutManager就可以控制显示不同的样式,RecyclerView提供的LayoutManager有:LinearLayoutManager横向或者纵向滑动;GridLayoutManager网格布局显示;StaggeredGridLayoutManager瀑布流显示效果。

  • RecyclerView可以通过ItemDecoration控制Item之间的间隔

  • RecyclerView可以通过ItemAnimator控制Item的增删动画

关于具体的RecyclerView的介绍推荐两篇博客,Android RecyclerView 使用完全解析 体验艺术般的控件 Android开发之RecyclerView的使用全解 这里就不在做过多的描述了。后面我们会通过几个例子体会一下RecyclerView的用法。

附上RecyclerView的国内镜像API

CardView

  CardView也是Android5.0推出的一个全新控件,CardView类似于FrameLayout,但是添加了圆角和阴影效果,常用于ListView和RecyclerView中,是一种容器,可以在CardView之上添加其它控件。下面我们了解一下CardView的常用属性:

  • card_view:cardElevation:阴影的大小
  • card_view:cardMaxElevation:阴影最大高度
  • card_view:cardBackgroundColor:卡片的背景色
  • card_view:cardCornerRadius:卡片的圆角大小
  • card_view:contentPadding:卡片内容的内边距
  • card_view:contentPaddingBottom:卡片内容的底部内边距
  • card_view:contentPaddingTop:卡片内容的上内边距
  • card_view:contentPaddingLeft:卡片内容的左内边距
  • card_view:contentPaddingRight:卡片内容的右内边距
  • card_view:contentPaddingStart:卡片内容的左内边距
  • card_view:contentPaddingEnd:卡片内容的右内边距
  • card_view:cardUseCompatPadding:设置内边距,V21+的版本和之前的版本仍旧具有一样的计算方式
  • card_view:cardPreventConrerOverlap:在V20和之前的版本中添加内边距,这个属性为了防止内容和边角的重叠

附上CardView的国内镜像API

关于SwiperefreshLayout、RecyclerView和CardView就简单介绍到这里,下面我们用几个例子体会一下这三个控件组合的效果:

使用RecyclerView需要在Gradle中添加:

compile 'com.android.support:recyclerview-v7:24.0.0'

使用CardView需要在Gradle中添加:

compile 'com.android.support:cardview-v7:24.0.0'

SwiperefreshLayout、RecyclerView和CardView组合实现普通的列表视图,有下拉刷新功能:

首先是布局文件的代码:


android:id="@+id/sl"
android:layout_
android:layout_>android:id="@+id/recycler"
android:layout_
android:layout_
android:cacheColorHint="@null"
android:scrollbars="vertical" />

Item布局文件代码:


xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cv_rvlist"
android:layout_
android:layout_
android:layout_margin="5dp"
card_view:cardCornerRadius="5dp">

接着是适配器的代码:

package com.example.newapidemo.adapter;import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import com.example.newapidemo.OnItemClickListener;
import com.example.newapidemo.R;
import com.example.newapidemo.domain.RVTest;import java.util.List;/*** Created by Devin on 2016/7/14.* 自定义RecyclerView的适配器*/
public class RVListAdapter extends RecyclerView.Adapter {private Context mContext;
private List datas;
private OnItemClickListener mListener;/*** 暴露出去的设置item点击事件** @param mListener*/
public void setOnItemClickListener(OnItemClickListener mListener) {this.mListener = mListener;
}public RVListAdapter(Context mContext, List datas) {this.mCOntext= mContext;this.datas = datas;
}/*** 为每一个Item inflate一个View,返回一个ViewHolder,将View封装在ViewHolder中,省略掉setTag和getTag的步骤** @param parent* @param viewType* @return*/@Override
public RVListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(mContext).inflate(R.layout.item_rvlist, parent, false);//给每一个item设置点击监听view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (mListener != null) {//调用getTag取出数据mListener.onItemClick(view, (String) view.getTag());}}});return new RVListViewHolder(view);
}/*** 将数据渲染到View中** @param holder* @param position*/
@Override
public void onBindViewHolder(RVListViewHolder holder, int position) {//将数据通过调用setTag方法保存在ItemView里面,然后可以调用getTag取出数据holder.itemView.setTag(datas.get(position).getContent());holder.iv_rvlist_icon.setImageResource(R.mipmap.ic_launcher);holder.tv_rvlist_text.setText(datas.get(position).getContent());
}/*** 获取到Item的数量** @return*/
@Override
public int getItemCount() {return datas.size();
}/*** 批量添加数据** @param testList*/
public void addItems(List testList) {if (testList != null) {datas.addAll(0, testList);notifyItemRangeChanged(0, testList.size());}
}/*** ViewHolder,需要继承RecyclerView.ViewHolder*/
public static class RVListViewHolder extends RecyclerView.ViewHolder {private ImageView iv_rvlist_icon;private TextView tv_rvlist_text;public RVListViewHolder(View itemView) {super(itemView);iv_rvlist_icon = (ImageView) itemView.findViewById(R.id.iv_rvlist_icon);tv_rvlist_text = (TextView) itemView.findViewById(R.id.tv_rvlist_text);}
}
}

由于RecyclerView不像ListView一样提供Item点击事件,所以我们需要自己去实现,Item点击和长按事件,按自己需求去实现,这里的话就实现Item点击事件。

最后是Activity代码:

package com.example.newapidemo;import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.view.View;import com.example.newapidemo.adapter.RVListAdapter;
import com.example.newapidemo.domain.RVTest;import java.util.ArrayList;
import java.util.List;/*** Created by Devin on 2016/7/14.*/
public class RVListActivity extends AppCompatActivity {
private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private RVListAdapter adapter;
private List datas;
public static String TAG = "RVListActivity";@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_rvlist);swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.sl);recyclerView = (RecyclerView) findViewById(R.id.recycler);linearLayoutManager = new LinearLayoutManager(this);//设置为垂直布局,这也是默认的linearLayoutManager.setOrientation(OrientationHelper.VERTICAL);//设置布局管理器recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));//设置增加或删除条目的动画recyclerView.setItemAnimator(new DefaultItemAnimator());datas = new ArrayList<>();initData();adapter = new RVListAdapter(this, datas);//设置适配器recyclerView.setAdapter(adapter);//设置Item点击监听adapter.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(View view, String data) {ToastUtils.showToast(RVListActivity.this, data);}});//设置刷新时动画的背景颜色swipeRefreshLayout.setProgressBackgroundColorSchemeResource(android.R.color.white);//设置下拉刷新时候动画的颜色,可以一次设置四个swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light,+android.R.color.holo_red_light, android.R.color.holo_orange_light,+android.R.color.holo_green_light);//设置刷新监听swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {new UpdateTask().execute();}});}/*** 初始化数据*/
private void initData() {for (int i = 0; i <20; i++) {datas.add(new RVTest(i, "这是第 " + (i + 1) + " 条测试数据"));}
}/*** 模拟加载数据*/
private class UpdateTask extends AsyncTask> {@Overrideprotected List doInBackground(Void... voids) {try {//休眠3秒钟Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}List data = new ArrayList<>();data.add(new RVTest(0, "下拉刷新出来的数据1"));data.add(new RVTest(1, "下拉刷新出来的数据2"));data.add(new RVTest(2, "下拉刷新出来的数据3"));return data;}@Overrideprotected void onPostExecute(List testList) {adapter.addItems(testList);//停止刷新swipeRefreshLayout.setRefreshing(false);//RecyclerView滑动到第一个recyclerView.scrollToPosition(0);ToastUtils.showToast(RVListActivity.this, "刷新了3条数据");}
}
}

在这里通过用SwiperefreshLayout实现下拉刷新功能,非常简单,下拉刷新加载数据在这里只是模拟网络请求数据,然后实现的效果图如下:

这里是实现类似于ListView的效果,不过用这种组合比较符合google的MD设计效果,在实际的开发中我们可以按需求扩展。下面是SwiperefreshLayout、RecyclerView和CardView实现网格效果

SwiperefreshLayout、RecyclerView和CardView实现网格效果:

首先依然是布局文件代码:


android:id="@+id/sl_grid"
android:layout_
android:layout_
android:orientation="vertical">

Item布局代码:


xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:layout_margin="3dp"
android:orientation="vertical"
android:padding="5dp"
card_view:cardCornerRadius="5dp">

接着是适配器代码,跟上面一个例子的适配器代码基本一样,就没有写那么多注释了:

package com.example.newapidemo.adapter;import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import com.example.newapidemo.OnItemClickListener;
import com.example.newapidemo.R;
import com.example.newapidemo.domain.RVTest;import java.util.List;/*** Created by Devin on 2016/7/14.*/
public class RVGridAdapter extends RecyclerView.Adapter {private Context mContext;
private List datas;
private OnItemClickListener onItemClickListener;public void setOnItemClickListener(OnItemClickListener listener) {this.OnItemClickListener= listener;
}public RVGridAdapter(Context mContext, List datas) {this.mCOntext= mContext;this.datas = datas;
}@Override
public RVGridViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(mContext).inflate(R.layout.item_rvgrid, parent, false);view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (onItemClickListener != null) {onItemClickListener.onItemClick(view, (String) view.getTag());}}});return new RVGridViewHolder(view);
}@Override
public void onBindViewHolder(RVGridViewHolder holder, int position) {holder.itemView.setTag(datas.get(position).getContent());holder.tv_rvgrid.setText(datas.get(position).getContent());
}@Override
public int getItemCount() {return datas.size();
}
/*** 批量添加数据** @param testList*/
public void addItems(List testList) {if (testList != null) {datas.addAll(0, testList);notifyItemRangeChanged(0, testList.size());}
}
public static class RVGridViewHolder extends RecyclerView.ViewHolder {TextView tv_rvgrid;public RVGridViewHolder(View itemView) {super(itemView);tv_rvgrid = (TextView) itemView.findViewById(R.id.tv_rvgrid);}
}
}

最后是Activity代码:

package com.example.newapidemo;import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;import com.example.newapidemo.adapter.RVGridAdapter;
import com.example.newapidemo.domain.RVTest;import java.util.ArrayList;
import java.util.List;/*** Created by Devin on 2016/7/14.*/
public class RVGridActivity extends AppCompatActivity {
private SwipeRefreshLayout sl_grid;
private RecyclerView rv_grid;
private GridLayoutManager gridLayoutManager;
private RVGridAdapter adapter;
private List datas;
private String[] names = {"浏览器", "工具", "图库", "设置", "微信", "安全", "电话", "短信", "QQ","联系人", "起点", "云音乐", "游戏", "爱消除", "系统","笔记", "随手记", "计算器", "文件", "天气"};@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_rvgrid);rv_grid = (RecyclerView) findViewById(R.id.rv_grid);sl_grid = (SwipeRefreshLayout) findViewById(R.id.sl_grid);gridLayoutManager = new GridLayoutManager(this, 4);rv_grid.setLayoutManager(gridLayoutManager);rv_grid.setItemAnimator(new DefaultItemAnimator());//设置刷新时动画的背景颜色sl_grid.setProgressBackgroundColorSchemeResource(android.R.color.white);//设置下拉刷新时候动画的颜色,可以一次设置四个sl_grid.setColorSchemeResources(android.R.color.holo_blue_light,+android.R.color.holo_red_light, android.R.color.holo_orange_light,+android.R.color.holo_green_light);initData();adapter = new RVGridAdapter(this, datas);rv_grid.setAdapter(adapter);adapter.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(View view, String data) {ToastUtils.showToast(RVGridActivity.this, "点击的是:" + data);}});sl_grid.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {new UpdateTask().execute();}});
}private void initData() {datas = new ArrayList<>();for (int i = 0; i <20; i++) {datas.add(new RVTest(i, names[i]));}
}/*** 模拟加载数据*/
private class UpdateTask extends AsyncTask> {@Overrideprotected List doInBackground(Void... voids) {try {//休眠3秒钟Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}List data = new ArrayList<>();data.add(new RVTest(0, "数据1"));data.add(new RVTest(1, "数据2"));data.add(new RVTest(2, "数据3"));data.add(new RVTest(2, "数据4"));return data;}@Overrideprotected void onPostExecute(List testList) {adapter.addItems(testList);//停止刷新sl_grid.setRefreshing(false);//RecyclerView滑动到第一个rv_grid.scrollToPosition(0);ToastUtils.showToast(RVGridActivity.this, "刷新了4条数据");}
}
}

其实这个例子跟上一个比较类似,只是在RecyclerView中传入不同的布局管理器而已,这样我们在实现网格效果就比较简单了,然后是效果图:

这里简单实现类似网格视图的效果,跟上一个例子比较相似,就不再做很多介绍了,下面是实现瀑布流的效果:

首先是布局文件代码:


android:id="@+id/sl_stagger"
android:layout_
android:layout_
android:orientation="vertical">

Item布局代码:


xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:layout_margin="5dp"
android:orientation="vertical"
card_view:cardBackgroundColor="#FFFF33"
android:padding="5dp"
card_view:cardCornerRadius="5dp">

适配器代码:

package com.example.newapidemo.adapter;import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import com.example.newapidemo.OnItemClickListener;
import com.example.newapidemo.R;
import com.example.newapidemo.domain.RVTest;import java.util.ArrayList;
import java.util.List;/*** Created by Devin on 2016/7/14.*/
public class RVStaggerAdapter extends RecyclerView.Adapter {
private Context mContext;
private List datas;
private OnItemClickListener onItemClickListener;
private List heights;public RVStaggerAdapter(Context mContext, List datas) {this.mCOntext= mContext;this.datas = datas;getRandomHeight(this.datas);
}public void setOnItemClickListener(OnItemClickListener listener) {this.OnItemClickListener= listener;
}@Override
public RVStaggerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(mContext).inflate(R.layout.item_rvstagger, parent, false);view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (onItemClickListener != null) {onItemClickListener.onItemClick(view, (String) view.getTag());}}});return new RVStaggerViewHolder(view);
}@Override
public void onBindViewHolder(RVStaggerViewHolder holder, int position) {//得到item的LayoutParams布局参数ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();//把随机的高度赋予item布局params.height = heights.get(position);//把params设置给item布局holder.itemView.setLayoutParams(params);holder.itemView.setTag(datas.get(position).getContent());holder.tv_rvstagger.setText(datas.get(position).getContent());
}@Override
public int getItemCount() {return datas.size();
}/*** 批量添加数据** @param testList*/
public void addItems(List testList) {if (testList != null) {datas.addAll(0, testList);notifyItemRangeChanged(0, testList.size());}
}/*** 随机得到Item的高度** @param lists*/
private void getRandomHeight(List lists) {heights = new ArrayList<>();for (int i = 0; i }public static class RVStaggerViewHolder extends RecyclerView.ViewHolder {TextView tv_rvstagger;public RVStaggerViewHolder(View itemView) {super(itemView);tv_rvstagger = (TextView) itemView.findViewById(R.id.tv_rvstagger);}
}}

最后是Activity代码:

package com.example.newapidemo;import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;import com.example.newapidemo.adapter.RVStaggerAdapter;
import com.example.newapidemo.domain.RVTest;import java.util.ArrayList;
import java.util.List;/*** Created by Devin on 2016/7/14.*/
public class RVStaggeredActivity extends AppCompatActivity {
private SwipeRefreshLayout sl_stagger;
private RecyclerView rv_stagger;
private StaggeredGridLayoutManager layoutManager;
private List datas;
private String[] names = {"浏览器", "工具", "图库", "设置", "微信", "安全", "电话", "短信", "QQ", "汽车"};
private int[] icOns= {R.drawable.icon0, R.drawable.icon1,R.drawable.icon2, R.drawable.icon3,R.drawable.icon4, R.drawable.icon5,R.drawable.icon6, R.drawable.icon7,R.drawable.icon8, R.drawable.icon9};
private RVStaggerAdapter adapter;@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_rvstagger);sl_stagger = (SwipeRefreshLayout) findViewById(R.id.sl_stagger);rv_stagger = (RecyclerView) findViewById(R.id.rv_stagger);layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);rv_stagger.setLayoutManager(layoutManager);initData();adapter = new RVStaggerAdapter(this, datas);rv_stagger.setAdapter(adapter);//设置刷新时动画的背景颜色sl_stagger.setProgressBackgroundColorSchemeResource(android.R.color.white);//设置下拉刷新时候动画的颜色,可以一次设置四个sl_stagger.setColorSchemeResources(android.R.color.holo_blue_light,+android.R.color.holo_red_light, android.R.color.holo_orange_light,+android.R.color.holo_green_light);adapter.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(View view, String data) {ToastUtils.showToast(RVStaggeredActivity.this, "点击的是:" + data);}});sl_stagger.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {new UpdateTask().execute();}});}private void initData() {datas = new ArrayList<>();for (int i = 0; i <30; i++) {datas.add(new RVTest(i, "原始数据" + i));}
}/*** 模拟加载数据*/
private class UpdateTask extends AsyncTask> {@Overrideprotected List doInBackground(Void... voids) {try {//休眠3秒钟Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}List data = new ArrayList<>();data.add(new RVTest(0, "数据1"));data.add(new RVTest(0, "数据2"));data.add(new RVTest(0, "数据3"));data.add(new RVTest(0, "数据4"));return data;}@Overrideprotected void onPostExecute(List testList) {adapter.addItems(testList);//停止刷新sl_stagger.setRefreshing(false);//RecyclerView滑动到第一个rv_stagger.scrollToPosition(0);ToastUtils.showToast(RVStaggeredActivity.this, "刷新了4条数据");}
}
}

实现效果图如下:

这样就可以实现瀑布流效果了,关于这三个控件的组合就简单介绍到这里,下一节,我们继续用这三个控件实现拖拽和滑动效果。




推荐阅读
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 微信小程序导航跟随的实现方法
    本文介绍了在微信小程序中实现导航跟随的方法。通过设置导航的position属性和绑定滚动事件,可以实现页面向下滚动到导航位置时,导航固定在页面最上方;页面向上滚动到导航位置时,导航恢复到原始位置;点击导航可以平滑跳转到相应位置。代码示例也给出了具体实现方法。 ... [详细]
author-avatar
4号的国哥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有