android 城市列表数据,用RecyclerView写的城市列表
分享一下城市列表的網格布局樣式的demo,代碼里面包括網格布局和豎直列表布局兩種樣式。
網格樣式:
image.png
豎直列表樣式:
image.png
數據來源,本地的citylist.json城市數據源如下截取,放在新建的raw文件夾下面:
[
{
"key": "A",
"list": [
{
"realname": "澳門",
"displayname": "澳門"
},
{
"realname": "阿勒泰地區",
"displayname": "阿勒泰"
},
{
"realname": "安康",
"displayname": "安康"
},
{
"realname": "安慶",
"displayname": "安慶"
},
{
"realname": "安順",
"displayname": "安順"
},
{
"realname": "安陽",
"displayname": "安陽"
},
{
"realname": "鞍山",
"displayname": "鞍山"
}
]
}
]
讀取數據成String類型,在根據key關鍵詞來解析數據。
public static String getFromRaw(Context context) {
String result = "";
try {
InputStream in = context.getResources().openRawResource(
R.raw.citylist);
// 獲取文件的字節數
int lenght = in.available();
// 創建byte數組
byte[] buffer = new byte[lenght];
// 將文件中的數據讀到byte數組中
in.read(buffer);
result = new String(buffer,"utf-8");
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
2.根據關鍵詞Key來解析數據。設計的方法是一共多少個字母就有多少個Item。其中item里面在include一個RecyclerView的網格布 局和一個TextView來顯示字母數據。所以在這里可以將解析的城市列表封裝成一個Map數據,key對應的是字母,而value城市列表名則用list數組來封裝,有多少個字母就新建對應的list來包含對應字母的所有城市名稱,詳見如下。(使用ArrayMap在數據量不大的情況下更省內存,性能更好):
//封裝城市列表map集合
private ArrayMap> map = new ArrayMap<>();
//封裝首字母list數組
private ArrayList nameSortsList = new ArrayList<>();
private void initData() {
String json = FileUtil.getFromRaw(this);
//解析數據
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String nameSort = jsonObject.getString("key");
JSONArray jsonCityArray = jsonObject.getJSONArray("list");
CityModel cityModel = new CityModel();
cityModel.setNameScort(nameSort);
addMap(nameSort, jsonCityArray);
nameSortsList.add(cityModel);//封裝字母列表數據成list
}
} catch (JSONException e) {
e.printStackTrace();
}
}
//添加到Map集合,key和解析的城市名組成的list相對應
private void addMap(String nameSort, JSONArray jsonCityArray) {
if (!map.containsKey(nameSort)) {
map.put(nameSort, new ArrayList());
}
for (int i = 0; i < jsonCityArray.length(); i++) {
CityModel cityModel = new CityModel();
try {
JSONObject jsonCityObject = jsonCityArray.getJSONObject(i);
String realName = jsonCityObject.getString("realname");
String displayName = jsonCityObject.getString("displayname");
cityModel.setCityName(displayName);
} catch (JSONException e) {
e.printStackTrace();
}
map.get(nameSort).add(cityModel);
}
}
3.數據封裝好后,再寫Adapter,這里參照網上大神封裝Adapter的方法,寫一個AbsAdapter來綁定ViewHolder,在寫一個BaseAdapter繼承AbsAdapter來封裝數據;ViewHolder封裝成BaseViewHolder,里面將Item對應的布局傳入形成對應的View,再將不同的View封裝成SparseArray的View數組,在里面findViewById找到對應填寫數據的子布局。三個基類代碼就不貼了,詳見Github源碼: https://github.com/yangfang521314/ListCity_RecyclerView_Demo。
整體Item的Adapter:
public class ItemAdapter extends BaseAdapter {
private RecyclerItemClickListener.OnItemClickListener onItemListener;
private ArrayMap> map;
private Context mContext;
private String style;
public ItemAdapter(Context context) {
super(context);
mContext = context;
}
@Override
protected ItemViewHolder createItemViewHolder(ViewGroup parent, int viewType) {
ItemViewHolder viewHolder = new ItemViewHolder(parent, R.layout.item_city_layout);
return viewHolder;
}
@Override
protected void bindCustomViewHolder(ItemViewHolder holder, int position) {
holder.mNameSort.setText(data.get(position).getNameScort());
if (map.containsKey(data.get(position).getNameScort())) {
CityListAdapter cityAdapter = new CityListAdapter(mContext);
cityAdapter.setData(map.get(data.get(position).getNameScort()));
cityAdapter.setOnClickListener(onItemListener);
if(style.equals("grid")){//網格布局
holder.mRecyclerView.setLayoutManager(new GridLayoutManager(mContext, 4));
holder.mRecyclerView.setAdapter(cityAdapter);
}
if(style.equals("list")){//豎直列表布局
holder.mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext,LinearLayoutManager.VERTICAL,false));
holder.mRecyclerView.setAdapter(cityAdapter);
}
}
}
@Override
public void setData(List list) {
data = list;
}
public void setCityName(ArrayMap> cityName) {
this.map = cityName;
}
public void setOnItmeListener(RecyclerItemClickListener.OnItemClickListener clickListener) {
this.onItemListener = clickListener;
}
public void setStyle(String style) {
this.style = style;//分兩種類型
}
}
具體城市列表名的Adapter
public class CityListAdapter extends BaseAdapter {
private RecyclerItemClickListener.OnItemClickListener onClickListener;
public CityListAdapter(Context context) {
super(context);
}
@Override
protected ItemViewHolder createItemViewHolder(ViewGroup parent, int viewType) {
return new ItemViewHolder(parent, R.layout.list_city_name);
}
@Override
protected void bindCustomViewHolder(final ItemViewHolder holder, final int position) {
holder.mCityName.setText(data.get(position).getCityName());
holder.mCityName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onClickListener.onItemClick(holder.mCityName,position);
}
});
}
public void setOnClickListener(RecyclerItemClickListener.OnItemClickListener onClickListener) {
this.onClickListener = onClickListener;
}
}
ItemViewHolder:
public class ItemViewHolder extends BaseViewHolder {
public TextView mNameSort;
public RecyclerView mRecyclerView;
public TextView mCityName;
public ItemViewHolder(ViewGroup parent, @LayoutRes int resId) {
super(parent, resId);
mNameSort = getView(R.id.header_tv);
mRecyclerView = getView(R.id.city_recyclerview);
mCityName = getView(R.id.tv_cityname);
}
}
4.主Activity代碼:
public class GridCityActivity extends AppCompatActivity implements RecyclerItemClickListener.OnItemClickListener {
//封裝城市列表數據
private ArrayMap> map = new ArrayMap<>();
//首字母數據
private ArrayList nameSortsList = new ArrayList<>();
private RecyclerView mRecyclerview;
private ItemAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_city_list);
Intent intent = getIntent();
String style = intent.getStringExtra("style");
initData();
initGridRecy(style);
}
private void initGridRecy(String style) {
mRecyclerview = (RecyclerView) findViewById(R.id.list_cyclerview);
mRecyclerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
adapter = new ItemAdapter(this);
adapter.setData(nameSortsList);
//列表和網格布局
adapter.setCityName(map);
adapter.setStyle(style);
adapter.setOnItmeListener(this);//自定義監聽方法
mRecyclerview.setAdapter(adapter);
}
private void initData() {
String json = FileUtil.getFromRaw(this);
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String nameSort = jsonObject.getString("key");
JSONArray jsonCityArray = jsonObject.getJSONArray("list");
CityModel cityModel = new CityModel();
cityModel.setNameScort(nameSort);
addMap(nameSort, jsonCityArray);
nameSortsList.add(cityModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void addMap(String nameSort, JSONArray jsonCityArray) {
if (!map.containsKey(nameSort)) {
map.put(nameSort, new ArrayList());
}
for (int i = 0; i < jsonCityArray.length(); i++) {
CityModel cityModel = new CityModel();
try {
JSONObject jsonCityObject = jsonCityArray.getJSONObject(i);
String realName = jsonCityObject.getString("realname");
String displayName = jsonCityObject.getString("displayname");
cityModel.setCityName(displayName);
} catch (JSONException e) {
e.printStackTrace();
}
map.get(nameSort).add(cityModel);
}
}
@Override
public void onItemClick(View view, int position) {
Toast.makeText(this, ((TextView) view).getText(), Toast.LENGTH_LONG).show();//自定義監聽
}
}
總結
以上是生活随笔為你收集整理的android 城市列表数据,用RecyclerView写的城市列表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android炫酷动画代码,Androi
- 下一篇: android 判断滑动方向,H5触摸事