Android UI控件之ListView实现圆角效果

今天在Android群里面有人再求圆角ListView的实现方式,正好自己以前实现过。因此就共享了现在将其实现方式写在博客中共他人学习。给出实现方式之前顺带加点自己的想法,感觉上android中方形的ListView还是太“硬性”,没有圆角的有亲和力。连Apple也为了“圆角”这个设计去申请专利。

看来圆角确实比较适合现在人们的喜好吧。

照老规矩先上两张效果图吧:

第一张:

第二张:

该方式主要就是需要重新去实现自己的ListView代码如下:

package com.kiritor.corner_listview; 

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.AdapterView;
import android.widget.ListView; 

/***
 * 自定义listview
 *
 * @author Kiritor
 *
 */
public class MyListView extends ListView {
 public MyListView(Context context) {
  super(context);
 } 

 public MyListView(Context context, AttributeSet attrs) {
  super(context, attrs);
 } 

 /****
  * 拦截触摸事件
  */
 @Override
 public boolean onTouchEvent(MotionEvent ev) {
  switch (ev.getAction()) {
  case MotionEvent.ACTION_DOWN:
   int x = (int) ev.getX();
   int y = (int) ev.getY();
   int itemnum = pointToPosition(x, y);
   if (itemnum == AdapterView.INVALID_POSITION)
    break;
   else {
    if (itemnum == 0) {
     if (itemnum == (getAdapter().getCount() - 1)) {
      // 只有一项数据,设置背景设置为圆角的
      setSelector(R.drawable.list_round);
     } else {
      // 第一项,设置为上面为圆角的
      setSelector(R.drawable.list_top_round);
     }
    } else if (itemnum == (getAdapter().getCount() - 1))
     // 最后一项,设置为下面为圆角的
     setSelector(R.drawable.list_bottom_round);
    else {
     // 中间项,不用设置为圆角
     setSelector(R.drawable.list_center_round);
    }
   }
   break;
  case MotionEvent.ACTION_UP:
   break;
  }
  return super.onTouchEvent(ev);
 }
}

MainActivity

package com.kiritor.corner_listview; 

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map; 

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast; 

public class MainActivity extends Activity implements OnItemClickListener {
 private MyListView listView_1, listView_2, listView_3;
 private ArrayList<Map<String, String>> listData, listData2, listData3;
 private SimpleAdapter adapter; 

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  setContentView(R.layout.main);
  listView_1 = (MyListView) findViewById(R.id.mylistview_1);
  listView_2 = (MyListView) findViewById(R.id.mylistview_2);
  listView_3 = (MyListView) findViewById(R.id.mylistview_3); 

  listView_1.setAdapter(getSimpleAdapter_1());
  listView_2.setAdapter(getSimpleAdapter_2());
  listView_3.setAdapter(getSimpleAdapter_3()); 

  listView_1.setOnItemClickListener(this);
  listView_2.setOnItemClickListener(this);
  listView_3.setOnItemClickListener(this); 

  setListViewHeightBasedOnChildren(listView_1);
  setListViewHeightBasedOnChildren(listView_2);
  setListViewHeightBasedOnChildren(listView_3);
 } 

 /**
  * 设置第一列数据
  */
 private SimpleAdapter getSimpleAdapter_1() {
  listData = new ArrayList<Map<String, String>>(); 

  Map<String, String> map = new HashMap<String, String>();
  map.put("text", "天气动画");
  listData.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "通知栏天气");
  listData.add(map); 

  return new SimpleAdapter(MainActivity.this, listData,
    R.layout.list_item, new String[] { "text" },
    new int[] { R.id.tv_list_item }); 

 } 

 /**
  * 设置第二列数据
  */
 private SimpleAdapter getSimpleAdapter_2() {
  listData2 = new ArrayList<Map<String, String>>(); 

  Map<String, String> map = new HashMap<String, String>();
  map.put("text", "桌面插件");
  listData2.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "绑定微博");
  listData2.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "天气分享");
  listData2.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "通知与提示");
  listData2.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "定时播报");
  listData2.add(map); 

  return new SimpleAdapter(MainActivity.this, listData2,
    R.layout.list_item, new String[] { "text" },
    new int[] { R.id.tv_list_item }); 

 } 

 /**
  * 设置第三列数据
  */
 private SimpleAdapter getSimpleAdapter_3() {
  listData3 = new ArrayList<Map<String, String>>(); 

  Map<String, String> map = new HashMap<String, String>();
  map.put("text", "检查新版本");
  listData3.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "发送建议");
  listData3.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "帮助");
  listData3.add(map); 

  map = new HashMap<String, String>();
  map.put("text", "关于");
  listData3.add(map); 

  return new SimpleAdapter(MainActivity.this, listData3,
    R.layout.list_item, new String[] { "text" },
    new int[] { R.id.tv_list_item }); 

 } 

 /***
  * 动态设置listview的高度
  *
  * @param listView
  */
 public void setListViewHeightBasedOnChildren(ListView listView) {
  ListAdapter listAdapter = listView.getAdapter();
  if (listAdapter == null) {
   return;
  }
  int totalHeight = 0;
  for (int i = 0; i < listAdapter.getCount(); i++) {
   View listItem = listAdapter.getView(i, null, listView);
   listItem.measure(0, 0);
   totalHeight += listItem.getMeasuredHeight();
  }
  ViewGroup.LayoutParams params = listView.getLayoutParams();
  params.height = totalHeight
    + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
  // params.height += 5;// if without this statement,the listview will be
  // a
  // little short
  // listView.getDividerHeight()获取子项间分隔符占用的高度
  // params.height最后得到整个ListView完整显示需要的高度
  listView.setLayoutParams(params);
 } 

 @Override
 public void onItemClick(AdapterView<?> parent, View view, int position,
   long id) { 

  if (parent == listView_1) {
   Map<String, String> map = listData.get(position);
   Toast.makeText(MainActivity.this, map.get("text"), 1).show();
  } else if (parent == listView_2) {
   Map<String, String> map = listData2.get(position);
   Toast.makeText(MainActivity.this, map.get("text"), 1).show();
  } else if (parent == listView_3) {
   Map<String, String> map = listData3.get(position);
   Toast.makeText(MainActivity.this, map.get("text"), 1).show();
  } 

 } 

}

差不多也就是这样了,还有相关资源文件。

这里就不一一给出了。

完整源码部分:ListView实现圆角效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android高级UI特效仿直播点赞动画效果
  • Android 仿抖音的评论列表的UI和效果的实现代码
  • Android UI新组件学习和使用
  • Android MIUI通知类短信权限的坑
  • Android UI 中的 ListView列表控件的示例
  • 浅谈Android RecyclerView UI的滚动控件示例
  • android开发仿ios的UIScrollView实例代码
  • Android Build Variants 为项目设置变种版本的方法
  • Android编程设计模式之Builder模式实例详解
  • Android UI控件之ImageSwitcher实现图片切换效果
  • Android UI控件之Gallery实现拖动式图片浏览效果
  • Android UI控件之ProgressBar进度条
  • Android UI控件之Spinner下拉列表效果
  • Android利用Espresso进行UI自动化测试的方法详解
  • Android编程处理窗口控件大小,形状,像素等UI元素工具类
  • Android build文件的删除的方法
  • android studio 一直卡在Gradle:Build Running的几种解决办法
  • 25个实用酷炫的Android开源UI框架
(0)

相关推荐

  • Android MIUI通知类短信权限的坑

    MIUI的坑爹设计还真不少.比如说,MIUI手机不插SIM卡就不能USB调试安装应用,好,插,结果又让你先登录小米账号(无话可说).MIUI权限申请也是坑! 就拿READ_SMS这个权限来说,按照安卓规范来动态申请,它不弹窗让用户允许,然后回调却是成功的,到设置里一看,该权限还是询问状态.这什么逻辑啊! 然后想实现自动填短信验证码,不好意识,我MIUI自定义了一个通知类短信权限(Service_SMS),你不知道怎么申请,也不知道怎么在manifest注册.所以你没有权,也限监听不到的.我也不知

  • Android UI控件之ImageSwitcher实现图片切换效果

    本文实例为大家分享了geSwitcher实现图片切换效果的具体代码,供大家参考,具体内容如下 从该名字就可以看出来,ImageSwitcher是一个图片切换控件,可以在一系列的图片中,逐张的显示特定的图片,利用该控件可以实现图片浏览器中的上一张,下一张的功能.其使用方法也较 为简单,不过需要注意的是ImageSwitcher在使用的时候需要一个ViewFactory,用来区分显示图片的容器和他的父窗口. 具体的用法直接看实例,照例,先上效果图 看看下一张的效果: 布局文件就不多谈了直接看Main

  • Android 仿抖音的评论列表的UI和效果的实现代码

    抖音是一款音乐创意短视频社交软件,是一个专注年轻人的15秒音乐短视频社区.用户可以通过这款软件选择歌曲,拍摄15秒的音乐短视频,形成自己的作品.此App已在Android各大应用商店和APP Store均有上线. 在design包里面 有一个 BottomSheetDialogFragment 这个Fragment,他已经帮我们处理好了手势,所以实现起来很简单.下面是代码: public class ItemListDialogFragment extends BottomSheetDialog

  • Android UI控件之ProgressBar进度条

    我们知道在所有的界面UI中进度条无疑是非常重要的一个,因为它可以给用户一个较为清晰的视觉效果:就是用户的操作的完成情况.这不是简单的完成与未完成,而是以一个进度的方式展示给用户的交互性更强了. 对于Android系统中的进度条如何使用呢?下一是简单的实现,并未做相关的美化处理. 依照惯例,先上效果图: 第一张: 第二张: 其中两个原型的进度条并未做任何的处理,水平进度条利用线程使之不停地增加减少. 具体实现首先看布局文件: <LinearLayout xmlns:android="http

  • Android编程设计模式之Builder模式实例详解

    本文实例讲述了Android编程设计模式之Builder模式.分享给大家供大家参考,具体如下: 一.介绍 Builder模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造流程.该模式是为了将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来. 因为一个复杂的对象有很多大量组成部分,例如车,有车轮.方向盘.发动机,还有各种小零件等,如何将这些部件装配成一辆汽车,这个装配过程很漫长,也很复杂,对于这种情况,为了在构建过程中对

  • Android UI 中的 ListView列表控件的示例

    当程序中有大量的数据需要展示时,就需要用到 ListView 啦.ListView 允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕. 1 基本用法 布局文件中加入 ListView: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/and

  • Android UI新组件学习和使用

    今天来学习总结一下,Android 后添加的一些新的组件和UI效果,Material Dialog,SwipeRefreshLayout,ListPopupWindow,PopupMenu等. Material Dialog 你还在为使用 Material Dialog 去引用第三方的library包么?现在告诉你一个好消息,其实Android 在V7包里面已经实现了 Material 风格的对话框,并且兼容到底版本了.你只需要在你的代码中使用V7中的Dialog即可实现以上图片效果了.代码如下

  • Android编程处理窗口控件大小,形状,像素等UI元素工具类

    本文实例讲述了Android编程处理窗口控件大小,形状,像素等UI元素工具类.分享给大家供大家参考,具体如下: /** * 处理窗口控件大小,形状,像素等工具类 * * @author chen.lin * */ public class UITools { /** * 把像素转化为dp * * @param context * @param px * @return */ public static int px2dip(Context context, float px) { float d

  • Android利用Espresso进行UI自动化测试的方法详解

    为什么需要UI自动化测试? 我有一个观点,对于重复的工作,那么程序都是可以代替的,我想这是作为一个程序员的一个基本素养(能偷懒的绝不干活).UI自动化测试就是为了应付一些重复的工作,比如说测试某个功能,那么从应用点击,再经过一系列的点击页面才能到达这个页面,然后进行测试,那么我们是不是可以写段代码让app自动跑起来,自动来到那个界面进行测试呢?答案是肯定的,这就是本文所要说的自动化测试. 引言 谷歌2013年的时候开源了espress,谷歌的思路是,等到它足够成熟和稳定以后,将其迁移到Andro

  • 浅谈Android RecyclerView UI的滚动控件示例

    ListView 由于其强大的功能,在过去的 Andorid 开发中使用非常广泛.不过 ListView 需要优化来提升运行效率,就像我们之前所优化的那样,否则性能将很差.还有就是只能够纵向滚动,如果要想实现横向移动,用 ListView 是做不到的. RecyclerView 可以说是一个增强版的 ListView .它不仅实现了和 ListView 同样的效果,而且还优化了 ListView 存在的各种不足. RecyclerView 现在可是官方推荐使用的滚动控件哦O(∩_∩)O~ 1 基

  • Android Build Variants 为项目设置变种版本的方法

    前言 在项目开发过程中,时常会碰到这种情况: 1.同一个Project的同一个API,有几个不同的接口,比如内部测试用的Server,和当前版本暴露给用户使用的Server: 2.同一个Project有免费版和收费版 3.同一个Project不同环境下有不同的Constants常量 当然我们可以简单的通过这种方式处理不同情况下的API: // GET 电影信息 String douban_movie_info = "/v2/movie/test/subject"; //String d

  • android开发仿ios的UIScrollView实例代码

    今天重新装了编译器,结果崩无极限,真是日了狗了了.刚刚才知道问题在哪边. 好了,说正事,对于ios开发我没接触,不是很了解,百度了半天,差不多就是UIScrollView的把.如果不对,请指证.具体什么效果呢,我刚才拿朋友的iphone手机看了下,iphone的设置界面,第一个列表往下拉可以继续滚,上拉同理.不过android好像没有自带的这种情况. 我把这种效果称为滚无极限的scollview. 下面就来上源码: 首先,最最最重要的就是判断当前视图是否为空,你空视图滚不滚好像没啥区别,除了an

  • 25个实用酷炫的Android开源UI框架

    最近找了一些合适开源控件,这样在日常工作中会更加省时,再此分享给大家,希望能对大家有帮助,此博文介绍的都是UI上面的框架,接下来会有其他的开源框架(如:HTTP框架.DB框架). 1.Side-Menu.Android 分类侧滑菜单,Yalantis 出品. 项目地址:https://github.com/Yalantis/Side-Menu.Android 2.Context-Menu.Android 可以方便快速集成漂亮带有动画效果的上下文菜单,Yalantis出品. 项目地址:https:

  • Android build文件的删除的方法

    本文介绍了Android 删除所有build编译文件,翻译磁盘空间,分享给大家,也给自己留个笔记,具体如下: public static void main(String[] args) { //传入一个目录. deleteFileWithThread("D:\\"); /** * 这里开了多个线程,提高效率 **/ private static void deleteFileWithThread(String path) { File file = new File(path); i

  • Android UI控件之Gallery实现拖动式图片浏览效果

    我们知道现在智能手机上都有这样一种功能,就是你在浏览图片的时候.不是硬性的点击按钮而是可以实现手指的拖动,划开效果.使用户具有更好的交互体验,不过这种效果是如何实现的呢? 在Android中是通过Gallery来实现拖动效果的. 通过Gallery可以实现各种各样的效果,此篇文章只是简要谈谈他的用法,至于后续的一些效果 有机会的时候做一个整理. 首先看看其简单实现吧!本次实例是通过选取图片实现类似设置背景的功能! 不过需要说明的是:图片不宜过大,否则容易内存溢出,android对大图片的支持不好

  • Android UI控件之Spinner下拉列表效果

    下拉列表---Spinner用于显示列表项,类似于一组单选按钮RadioButton.Spinner的使用,可以极大的提升用户的体验性.当需要用户选择的时候,可以提供一个下拉列表项给用户选择. 具体来说下拉列表是如何实现的呢? 通过查阅API知道Spinner继承AdapterView,因此它的数据源需要通过Adapter实现. 一般来说Spinner的数据源可以是数组,也可以是一个XML文件. 一.以数组作为数据源 这种实现方式比较简单,先上效果图: xml文件代码; <LinearLayou

  • android studio 一直卡在Gradle:Build Running的几种解决办法

    在使用AS开发安卓应用程序的时候经常会遇到Gradle build running一直在运行甚至卡死的情况,解决方法如下: 方法1: 1.在C:\User\<用户名>\.gradle 目录下新建一个gradle.properties文件,并在里面添加一行:org.gradle.daemon=true 2.打开AS,在Settings中设置Gradle的工作模式为offline,如下图: 这样就可以解决一直在running的问题了 方法2: 找到路径C:\Users\admin\.gradle\

  • Android高级UI特效仿直播点赞动画效果

    本文给大家分享高级UI特效仿直播点赞效果-一个优美炫酷的点赞动画,具体实现代码大家参考本文. 效果图如下: 攻克难点: 心形图片的路径等走向 心形图片的控制范围 部分代码如下: 通过AbstractPathAnimator定义飘心动画控制器 @Override public void start(final View child, final ViewGroup parent) { parent.addView(child, new ViewGroup.LayoutParams(mConfig.

随机推荐