精华内容
下载资源
问答
  • 在实现分栏显示时,根据保存查询结果的对象不同,使用的方法也不同。 2.实施过程 缩略图显示方式是将数据中的图片及标题分栏等简要信息显示在主页面中,例如在开发“电子商务”网站,就使用了缩微图的显示...

    缩略图显示方式也就是分栏显示方式,适用于数据中包括图片,并且图片能够清楚的表现整条数据的实际含义的情况。采用该方法可以很直观的找到所需信息。经常应用于展示企业信息和商品信息等。下面将详细介绍缩略图显示方式。

    1.方案分析

    在实现应用缩略图显示方式显示搜索结果时,需要判断查询结果是否为空,只有查询结果不为空时,才可以分栏显示搜索结果。在实现分栏显示时,根据保存查询结果的对象不同,使用的方法也不同。

    2.实施过程

    缩略图显示方式是将数据中的图片及标题分栏等简要信息显示在主页面中,例如在开发“电子商务”网站,就使用了缩微图的显示方式,如图所示。当在页面左侧的搜索板块中选择类别为“电视区”,然后根据关键字“电视”进行查询,就会搜索出符合这两个查询条件的所有数据。如果数据带有相关的图片并且希望将搜索的数据直观的表现出来,那么就可以使用缩微图的方式来显示数据。

    图  缩微图的显示方式

    程序实现具体步骤:

    (1)新建一个网站命名为01,默认主页为Default.aspx。

    (2)在页面中添加一个DataList控件,用于显示所有的产品。

    (3)新建一个名为left.ascx的Web用户控件,在控件上添加一个DropDownList控件,用于设置查询的范围。添加一个TextBox控件,用于输入查询关键字。添加一个Button控件,用于提交查询。

    (4)新建一个名为search.aspx的页,在此页上添加一个DataList控件,用于显示查询结果。

    (5)程序主要代码如下。

    首先在Web.config文件中进行数据库连接配置,具体代码如下。

       <appSettings>

          <add key="ccc" value="Server=.;User id=sa;pwd=;DataBase=db_04"></add>

       </appSettings>

       设置好各项查询条件之后,单击【搜索】按钮进行查询。其原理是先获得下拉列表和问本框中的值,然后将这两个值通过显性传参的方式传递到search.aspx中,具体代码如下。

     protected void Button3_Click(object sender, EventArgs e)

        {

            string str = DropDownList1.SelectedValue.ToString();

            string key = TextBox1.Text.Trim().ToString();

            Response.Redirect("search.aspx?stype="+str+"&key="+key);

        }

    在search.aspx中首先判断传递过来的参数key是否为空,如果为空,说明文本框中没有输入任何关键字,则将和选择的类别相关的所有数据按照编号的降序排列显示出来。如果不为空,则将会根据传递过来的参数stype和参数key进行查询,然后将查询的数据显示出来。具体代码如下。

          SqlConnection strcon = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["ccc"]);

        protected void Page_Load(object sender, EventArgs e)

        {

            string newque;

            int stype = Convert.ToInt32(Request.QueryString["stype"]);

            string key = Request.QueryString["key"].ToString();

            if (key == "")

            {

                newque = "select * from tb_goods where typeid='" + stype + "' order by id desc";

            }

            else

            {

                newque = "select * from tb_goods where typeid='" + stype + "' and goodsname like '%" + key + "%'";

            }

            DataList1.DataSource = DataBase.ReDataSet(newque);

            DataList1.DataKeyField = "id";

            DataList1.DataBind();

            string supertype = "select * from tb_supertype";

            string subtype = "select * from tb_subtype";

            DataSet dssuper = DataBase.ReDataSet(supertype);

            DataSet dssub = DataBase.ReDataSet(subtype);

            DataRow[] rows = dssuper.Tables[0].Select();

            DataRow[] subrows = dssub.Tables[0].Select();

            if (!IsPostBack)

            {

                foreach (DataRow row in rows)

                {

                    TreeNode nd = new TreeNode();

                    nd.Text = row["typename"].ToString();

                    nd.Value = row["id"].ToString();

                    TreeView1.Nodes.Add(nd);

                    foreach (DataRow subrow in subrows)

                    {

                        TreeNode subnd = new TreeNode();

                        subnd.Text = subrow["typename"].ToString();

                        subnd.Value = subrow["id"].ToString();

                        if (subrow["supertype"].ToString() == row["id"].ToString())

                        {

                            nd.ChildNodes.Add(subnd);

                        }

                    }

                }

            }

        }

                                                                                                    ——摘自《C#编程词典》

    展开全文
  • 而且修改成不同的栏还十分方便! flex布局教程: https://www.runoob.com/w3cnote/flex-grammar.htm l 注意: css3中定义原生变量var浏览器兼容性不太好,如图:     转载于:...

    以下例子基于分四栏+栏间有间距的例子分析

    效果图:

     html代码: 

    <div class="buy-one-buy">
       <h3>淘一淘</h3>
        <ul>
           <li><img src="../img/homePage/rotation-1.jpg" alt="First buy"></li>
           <li><img src="../img/homePage/rotation-1.jpg" alt="Second buy"></li>
           <li><img src="../img/homePage/rotation-2.jpg" alt="Third buy"></li>
           <li><img src="../img/homePage/rotation-3.jpg" alt="Four slide"></li>
       </ul>
    </div>

     

    1.最简单粗暴的方式就是通过固定值+margin去计算

    • 首先我先固定了最外层的宽度为1200px;(这里为1202px宽度是因为我加了一个红边框方便观察,最后页面显示的时候要记得把border去掉并且宽度改为1200px)
      .buy-one-buy{
          width: 1202px;
          border: 1px solid red;
          margin: 0 auto;
      }

       

    • 之后我将每个li的宽度固定为288px(四个li即为1152px,剩下还有1200px-1152px=48px作为四栏中的间距(四栏共有三个间距,则48px/3=16px)。因此我给每个li设置margin-right为16px,当然最后一个li中的amrgin-right要设置为0。)   注意:因为li是块元素,我首先先把它转换为行内块元素再进行操作。所以先在ul中清除掉行内块的默认间距(font-size:0)。
      .buy-one-buy ul{
          font-size: 0;
      }
      .buy-one-buy li{
          display: inline-block;
          width: 288px;
          height: 140px;
          margin-right: 16px;
      } 
      .buy-one-buy li:last-child{
          margin-right: 0;
      }
    • 最后就能实现上图中的分栏效果了                                                     

    2.使用第一种方法会使得页面维护起来很麻烦,每次宽度都要去计算。所以后来,我使用float+margin+百分比实现一样的效果,之后维护只需要修改相应的百分比即可

    • 首先依旧固定住最外层的宽度
      .buy-one-buy{
          width: 1202px;/*之后要改回去1200*/
          border: 1px solid red;
          margin: 0 auto;
      }
    • 之后在li中使用float让他们位于同一行,给每个li的宽度设置为22%(原本应为父元素的1/4,即25%。但是需要留剩下的百分比给间距)。然后100%-22%*4=12%(即为三个间距的总宽度,每个间距宽度为4%);
      .buy-one-buy li{
          float: left;
          width: 22%;
          margin-right: 4%;
          height: 180px;
      }
      .buy-one-buy li:last-child{
          margin-right: 0%;
      }
      .buy-one-buy img{
          width: 100%;
          height: 100%;
      }
    • 最后也能实现一样的效果(但在实际上也可以将float变成display:inline-block;但是需要消除默认间距。也一样能实现)

    3.上诉两种方式如果页面一直固定为四栏的话,是可行的。但是如果维护的时候需要变成三栏五栏之类的就会需要修改一系列的css数据,并且平分的时候还不一定是整数。所以,最后我决定采用flex布局+css3去实现

    • 依旧固定住最外层的宽度
      .buy-one-buy{
          width: 1202px;/*之后要改回去1200*/
          border: 1px solid red;
          margin: 0 auto;
      }
    • 然后在ul中(li列表的父元素)使用flex布局(这里自定义了一个属性n:为你需要分栏的数字,之后的li根据这个属性去动态计算宽度)
      .buy-one-buy ul{
          display: flex;
          justify-content: space-between;/*两端对齐,项目之间的间隔都相等*/
          --n : 4;/*css自定义属性(--*),用var(--*)使用自定义属性*/
      }
    • 将每个li设置宽度和高度(其中不需要将li转换成行内块元素,因为flex布局默认flex-direction属性的主轴方向为水平方向)(这里使用了css3中的calc函数)
      .buy-one-buy li{
          width: calc(calc((100/var(--n))*1%) - 20px);   
          height: 100px;
      }
      .buy-one-buy img{
          width: 100%;
          height: 100%;
      }
    • 最后,就能成功实现上述效果了!而且修改成不同的栏还十分方便!
    • flex布局教程:https://www.runoob.com/w3cnote/flex-grammar.html

    注意: css3中定义原生变量var浏览器兼容性不太好,如图:

         

     

    转载于:https://www.cnblogs.com/ahaMOMO/p/11521628.html

    展开全文
  • 媒体查询和Bootstrap都是针对不同屏幕宽度进行的自适应,而并不会根据内容自动调整,无法满足我们的要求。 似乎浮动可以根据内容大小来进行自动排列,但和我们的需求相比也有一个很大的差别。那就是ls命令在调整好...

    最近项目上要在浏览器端实现一个类似 Linux 下 ls 命令的显示效果。虽然实现过程没花多长时间,但是觉得这个效果还挺赞的,所以分享一下。

    神奇的ls命令

    ls命令对于前端同学可能比较陌生,简单来说就是Linux终端中的一个常用功能,用来显示某个目录下的文件(夹)列表。不过这它的功能不是本文讨论的重点。重点是它神奇的显示效果,比如下面这样:

    AAffA0nNPuCLAAAAAElFTkSuQmCC

    看似并无神奇之处,就是文件(夹)名称逐行显示而已,别急,再来看下面两张截图:

    AAffA0nNPuCLAAAAAElFTkSuQmCC

    AAffA0nNPuCLAAAAAElFTkSuQmCC

    不知道你现在有没有发现布局发生了变化:由最初的1列变成了多列!

    你很容易想到列数量会随着窗口的宽度而改变,这种猜测是对的,但并不全面,因为决定其显示排列的还有文件(夹)名本身的长度。比如我再指定目录执行一条 ls 命令进行对比:

    AAffA0nNPuCLAAAAAElFTkSuQmCC

    两条命令执行时窗口宽度是一样的,但是在长文件(夹)名的情况下是3列,而短文件(夹)下是4列。

    ok~了解完ls命令的显示特点之后问题来了,我们该怎么实现呢?

    实现难点与解决方案

    更多文章请关注公众号“Web学习社”。

    这种列数发生变化的情况在网站页面中并不少见,你可能第一个就会想到媒体查询或者Bootstrap。但很遗憾事情并没有这么简单。媒体查询和Bootstrap都是针对不同屏幕宽度进行的自适应,而并不会根据内容自动调整,无法满足我们的要求。

    似乎浮动可以根据内容大小来进行自动排列,但和我们的需求相比也有一个很大的差别。那就是ls命令在调整好合适的列数之后,每列文件(夹)名都是等宽左对齐的。而使用浮动后的效果是每行长的名称排列少,短的名称排列多,造成列数不统一,参差不齐。

    到此看似毫无头绪,不过可以参考“把大象放进冰箱里”分几步的例子,分步骤来解决这个问题。这个问题我们其实可以分两步进行分析:

    显示的列数需要根据窗口大小和名称长度两者共同决定,按照已知的使用css的方式无法解决。那么我们只能用最笨的方式进行动态计算。

    列数确定以后要确保每列等宽等间距,且左对齐,这个比较容易实现,可以设置等宽等间距。

    按照这个思路我们来实现第1步,那就是怎么计算出合适的列数。看看列数是由哪些因素决定的:

    窗口的宽度。

    名称的长度。

    名称之间的横向间距。

    窗口的宽度可以通过dom获取或者样式设定,名称宽度可以通过fontSize进行计算,一般一个中文字符宽度为一个fontSize值,而英文数字则为一半,这里我们为了方便计算,只考虑英文和数字的情况。横向间距则可以由样式设定。那么可以得出计算公式:

    窗口宽度 >= 列数 * (名称长度 * fontSize/2 + 间距)

    这个不等式并不准确,因为当列数等于1的时候是最有可能满足这个不等式的,但显然不是我们想要的结果,所以还要加上另一个不等式:

    窗口宽度 < (列数 + 1) * (名称长度 * fontSize/2 + 间距)

    满足这两个条件的列数才是我们的最优解。不等式右边的表达式实际上就是行宽,更准确的说是每一行的行宽。当然这个表达式其实也不严谨,更严谨的是下面这样:

    窗口宽度 >= (名称长度1 * fontSize/2 + 间距) + ... + (名称长度n * fontSize/2 + 间距)

    窗口宽度 < (名称长度1 * fontSize/2 + 间距) + ... + (名称长度n+1 * fontSize/2 + 间距)

    代码如下:

    / **

    * 根据列数和名称长度进行分列,以二维数组的方式返回结果,如果超出宽度则返回空数组

    * list {Array} 待分列的名称数组

    * colnum {Number} 列数

    * size {Number} 字体大小

    * width {Number} 用父容器的宽度替代前面所说的窗口宽度

    * spaceWidth {Number} 间距

    */

    var subfield = function(list, colnum, size, width, spaceWidth) {

    // 使用lodash的chunk函数将数组按照列数分割成二维数组

    var result = _.chunk(list, Math.min(colnum, list.length))

    var rowWidth = 0

    // 逐列计算宽度

    for(var col=0;col

    colWidth = 0

    for(var row=0; row

    var item = result[row][col] || ''

    // 每列宽度取决于最长的名称宽度

    colWidth = Math.max(colWidth, item.length * size / 2 + spaceWidth)

    }

    rowWidth += colWidth

    }

    return rowWidth < width ? result : []

    }

    有了上面的不等式,那么现在我们就可以开始逐行计算了,不过我们从分几列开始算起?如果从分1列的方式算起,那么大多数情况下前面的分列方式都不是最优解,所以我们考虑直接从最优解算起,找到最长的名称和最短的名称并假设它们在一列,如果不满足则减少一列。

    // 先取最理想的列数

    var colnum = Math.max(1, Math.floor((containerWidth - maxFile.length * fontSize / 2 - spaceWidth) / (spaceWidth + fontSize / 2 * minFile.length)))

    var result = []

    // 按照递减方式直到找到最优解

    while (colnum > 0 && result.length===0) {

    if (colnum === 1) {

    result = []

    for(var i=files.length;i>0;i--) {

    result.push([files.shift()])

    }

    } else {

    result = subfield(files, colnum, fontSize, containerWidth, spaceWidth)

    }

    colnum--

    }

    至此,我们就完成了第1步。第2步这种布局方式其实很常见,其实就是古老的table布局,那么我们渲染到页面的时候直接使用table来实现。

    var render = function(list) {

    var str = ''

    list.forEach(function(row) {

    str += '

    '+ row.join('') + ''

    })

    document.querySelector('.ls table').innerHTML = str

    }

    具体代码:

    AAffA0nNPuCLAAAAAElFTkSuQmCC

    展开全文
  • 之前我遇到过这样的需求,要求在ListView中按时间对数据分栏,当时的做法是在每个ListView的item中加入时间栏的布局,然后在代码中控制时间栏 的显示与隐藏。 但其实重写Adapter两个方法后就可以完成这个任务,当...

    之前我遇到过这样的需求,要求在ListView中按时间对数据分栏,当时的做法是在每个ListView的item中加入时间栏的布局,然后在代码中控制时间栏

    的显示与隐藏。

    但其实重写Adapter两个方法后就可以完成这个任务,当ListView中带有不同布局的时候,可以根据itemType来加载不同的布局。

    int getItemViewType(int position) 返回指定position的itemView的viewType,用于加载不同布局。此方法必须返回0到getViewTypeCount()-1

    的数字或者IGNORE_ITEM_VIEW_TYPE。

    int getViewTypeCount() 返回你这个ListView有多少个不同的布局。

    让我们先来看看两张分栏后的效果图:

         

    这里按照歌曲名拼音的首字母分栏,把汉字转为拼音我用了Pinyin4j,例如"你好"可转为"NIHAO",由于这不是这篇文章的重点,不知道的可自行百度。

    那么下面来看看怎么一步步地实现吧!

    1.由图中列表可以看出,我们要显示歌曲名,歌手名,分栏需要用到歌曲名对应的汉字拼音,所以有了下面的MediaItem实体。

     1 public class MediaItem implements Serializable {
     2     private static final long serialVersionUID = 1L;
     3 
     4     private int id; // ID
     5     private String songName; // 歌曲名
     6     private String singerName; // 歌手名
     7     private String sortKey; // 歌曲名的拼音(如"你好"-->"NIHAO")
     8 
     9     public String getSongName() {
    10         return songName;
    11     }
    12 
    13     public void setSongName(String songName) {
    14         this.songName = songName;
    15     }
    16 
    17     public String getSingerName() {
    18         return singerName;
    19     }
    20 
    21     public void setSingerName(String singerName) {
    22         this.singerName = singerName;
    23     }
    24 
    25     public int getId() {
    26         return id;
    27     }
    28 
    29     public void setId(int id) {
    30         this.id = id;
    31     }
    32 
    33     public String getSortKey() {
    34         return sortKey;
    35     }
    36 
    37     public void setSortKey(String sortKey) {
    38         this.sortKey = sortKey;
    39     }
    40 }

    2.接下来就是需要从数据库中查出歌曲信息,使用android提供的uri:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI查询我们需要的字段,

    然后封装成MediaItem实体,用于绑定ListView。如果查询时间超过500毫秒,则显示加载的progressBar。

    布局比较简单,就是一个ListView和一个ProgressBar,我就不贴出来了。

     1 public class MediaActivity extends Activity {
     2     private static final String TAG = "MediaActivity";
     3 
     4     private static final int MSG_SHOW_PROGRESS_BAR = 100;
     5 
     6     private List<MediaItem> mList;
     7     private MediaAdapter mAdapter;
     8     private ListView mListView;
     9     private ProgressBar mProgressBar;
    10 
    11     @Override
    12     protected void onCreate(Bundle savedInstanceState) {
    13         super.onCreate(savedInstanceState);
    14         setContentView(R.layout.activity_media);
    15 
    16         initViews();
    17         // 查询音乐列表
    18         getData();
    19     }
    20 
    21     private void initViews() {
    22         mListView = (ListView) findViewById(R.id.media_list);
    23         mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
    24         ViewCompat.setOverScrollMode(mListView, ViewCompat.OVER_SCROLL_NEVER);
    25     }
    26 
    27     private void getData() {
    28         mList = new ArrayList<MediaItem>();
    29         // 如果500毫秒内加载完成,则不显示ProgressBar
    30         mHander.sendEmptyMessageDelayed(MSG_SHOW_PROGRESS_BAR, 500);
    31         // 使用AsyncTask查询音乐列表,并构造实体列表MediaItem
    32         new AsyncTask<Void, Void, List<MediaItem>>() {
    33 
    34             @Override
    35             protected List<MediaItem> doInBackground(Void... params) {
    36                 Log.v(LogUtils.TAG, "AsyncTask doInBackground");
    37                 Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    38                 String[] projection = { MediaStore.Audio.Media._ID, // ID
    39                         MediaStore.Audio.Media.TITLE, // 显示的歌曲名
    40                         MediaStore.Audio.Media.ARTIST // 艺术家
    41                 };
    42                 Cursor cursor = getContentResolver().query(uri, projection, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
    43                 if (cursor != null) {
    44                     try {
    45                         while (cursor.moveToNext()) {
    46                             MediaItem item = new MediaItem();
    47                             String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
    48                             item.setId(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));
    49                             item.setSongName(title);
    50                             item.setSingerName(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)));
    51                             // 汉字转拼音
    52                             item.setSortKey(PinYinUtils.getPinYin(title));
    53                             mList.add(item);
    54                         }
    55                     } catch (Exception e) {
    56                         Log.e(TAG, "get cursor data error!");
    57                     } finally {
    58                         cursor.close();
    59                     }
    60                 }
    61                 return mList;
    62             }
    63 
    64             @Override
    65             protected void onPostExecute(List<MediaItem> result) {
    66                 Log.v(LogUtils.TAG, "AsyncTask onPostExecute result.size=" + result.size());
    67                 mHander.removeMessages(MSG_SHOW_PROGRESS_BAR);
    68                 mAdapter = new MediaAdapter(MediaActivity.this, mList);
    69                 mListView.setAdapter(mAdapter);
    70                 mListView.setVisibility(View.VISIBLE);
    71                 if (mProgressBar.getVisibility() == View.VISIBLE) {
    72                     mProgressBar.setVisibility(View.GONE);
    73                 }
    74             }
    75         }.execute();
    76     }
    77 
    78     // 用于显示ProgressBar
    79     Handler mHander = new Handler(new Callback() {
    80         @Override
    81         public boolean handleMessage(Message msg) {
    82             switch (msg.what) {
    83             case MSG_SHOW_PROGRESS_BAR:
    84                 mProgressBar.setVisibility(View.VISIBLE);
    85                 break;
    86 
    87             default:
    88                 break;
    89             }
    90             return false;
    91         }
    92     });
    93 
    94 }

    3.接下来就是比较重要的Adapter,分栏的任务在这里完成。首先注意adapter绑定的数据源是一个List<TypeItem>,TypeItem对数据做了一层

    封装,它包含itemType,就是在getItemViewType()需要返回的参数。而通过generateItems()方法把传入的List<MediaItem>构造成

    List<TypeItem>,再加入itemType的同时如果发现MediaItem中歌曲名的拼音首字母不一样,就插入一个分组的头部。然后在getView()中就可以

    根据itemType来区分不同的布局,由于具有两个不同的布局,所以定义ViewHolder基类,分栏布局HeaderViewHolder和歌曲列表MediaViewHolder

    都继承自ViewHolder,用于缓存视图,然后就可以根据不同的ViewHolder实例来绑定数据(在ListView中有多个布局的时候都可以使用此方法)。

      1 package com.yangy.test.adapter;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 
      6 import android.content.Context;
      7 import android.view.LayoutInflater;
      8 import android.view.View;
      9 import android.view.ViewGroup;
     10 import android.widget.BaseAdapter;
     11 import android.widget.TextView;
     12 
     13 import com.yangy.test.model.MediaItem;
     14 import com.yy.gallerytest.activity.R;
     15 
     16 public class MediaAdapter extends BaseAdapter {
     17     
     18     private static final int VIEW_TYPE_COUNT = 2; // 有几种不同的布局
     19     private static final int VIEW_TYPE_HEADER = 0; // 分组的头部
     20     private static final int VIEW_TYPE_ITEM = 1; // 音乐列表item
     21 
     22     private LayoutInflater mInflater;
     23     private List<TypeItem> items;
     24 
     25     public MediaAdapter(Context context, List<MediaItem> items) {
     26         mInflater = LayoutInflater.from(context);
     27         this.items = generateItems(items);
     28     }
     29 
     30     /**
     31      * 实体基类,包含itemType,以便区分不同的布局,子类需要的其他数据可自行指定
     32      */
     33     class TypeItem {
     34         int itemType;
     35 
     36         public TypeItem(int itemType) {
     37             this.itemType = itemType;
     38         }
     39     }
     40 
     41     /**
     42      * 音乐列表实体,指定itemType为VIEW_TYPE_ITEM 包含MediaItem实体
     43      */
     44     class MediaTypeItem extends TypeItem {
     45         MediaItem mediaItem;
     46 
     47         public MediaTypeItem(MediaItem mediaItem) {
     48             super(VIEW_TYPE_ITEM);
     49             this.mediaItem = mediaItem;
     50         }
     51     }
     52 
     53     /**
     54      * 头布局实体,指定itemType为VIEW_TYPE_HEADER 包含分组中头部的字母
     55      */
     56     class HeaderTypeItem extends TypeItem {
     57         char header;
     58 
     59         public HeaderTypeItem(char header) {
     60             super(VIEW_TYPE_HEADER);
     61             this.header = header;
     62         }
     63     }
     64 
     65     /**
     66      * 根据传入的mediaItem list,构造带有header的TypeItem
     67      * 
     68      * @param mediaItems
     69      *            音乐列表实体
     70      * @return 包含itemType的实体
     71      */
     72     private List<TypeItem> generateItems(List<MediaItem> mediaItems) {
     73         List<TypeItem> items = new ArrayList<TypeItem>();
     74         int size = mediaItems == null ? 0 : mediaItems.size();
     75         char currIndex;
     76         char preIndex = '{';
     77         for (int i = 0; i < size; i++) {
     78             currIndex = mediaItems.get(i).getSortKey().charAt(0);
     79             // 是第一个item或者两个数据的拼音首字母不相等则插入头部
     80             if (i == 0 || currIndex != preIndex) {
     81                 items.add(new HeaderTypeItem(currIndex));
     82             }
     83             items.add(new MediaTypeItem(mediaItems.get(i)));
     84             preIndex = currIndex;
     85         }
     86         return items;
     87     }
     88 
     89     /**
     90      * ViewHolder基类,itemView用于查找子view
     91      */
     92     class ViewHolder {
     93         View itemView;
     94 
     95         public ViewHolder(View itemView) {
     96             if (itemView == null) {
     97                 throw new IllegalArgumentException("itemView can not be null!");
     98             }
     99             this.itemView = itemView;
    100         }
    101     }
    102 
    103     /**
    104      * 音乐列表ViewHolder
    105      */
    106     class MediaViewHolder extends ViewHolder {
    107         TextView songName;
    108         TextView singerName;
    109 
    110         public MediaViewHolder(View view) {
    111             super(view);
    112             songName = (TextView) view.findViewById(R.id.song_name);
    113             singerName = (TextView) view.findViewById(R.id.singer_name);
    114         }
    115     }
    116 
    117     /**
    118      * 头部ViewHolder
    119      */
    120     class HeaderViewHolder extends ViewHolder {
    121         TextView header;
    122 
    123         public HeaderViewHolder(View view) {
    124             super(view);
    125             header = (TextView) view.findViewById(R.id.header);
    126         }
    127     }
    128 
    129     @Override
    130     public View getView(int postion, View convertView, ViewGroup parent) {
    131         TypeItem item = items.get(postion);
    132         ViewHolder viewHolder;
    133         if (convertView == null) {
    134             // 根据不同的viewType,初始化不同的布局
    135             switch (getItemViewType(postion)) {
    136             case VIEW_TYPE_HEADER:
    137                 viewHolder = new HeaderViewHolder(mInflater.inflate(R.layout.media_header_item, null));
    138                 break;
    139             case VIEW_TYPE_ITEM:
    140                 viewHolder = new MediaViewHolder(mInflater.inflate(R.layout.media_item, null));
    141                 break;
    142 
    143             default:
    144                 throw new IllegalArgumentException("invalid view type : " + getItemViewType(postion));
    145             }
    146 
    147             // 缓存header与item视图
    148             convertView = viewHolder.itemView;
    149             convertView.setTag(viewHolder);
    150         } else {
    151             viewHolder = (ViewHolder) convertView.getTag();
    152         }
    153 
    154         // 根据初始化的不同布局,绑定数据
    155         if (viewHolder instanceof HeaderViewHolder) {
    156             ((HeaderViewHolder) viewHolder).header.setText(String.valueOf(((HeaderTypeItem) item).header));
    157         } else if (viewHolder instanceof MediaViewHolder) {
    158             onBindMediaItem((MediaViewHolder) viewHolder, ((MediaTypeItem) item).mediaItem);
    159         }
    160         return convertView;
    161     }
    162     
    163     private void onBindMediaItem(MediaViewHolder viewHolder, MediaItem mediaItem) {
    164         viewHolder.songName.setText(mediaItem.getSongName());
    165         viewHolder.singerName.setText(mediaItem.getSingerName());
    166     }
    167 
    168     @Override
    169     public int getItemViewType(int position) {
    170         if (items != null) {
    171             return items.get(position).itemType;
    172         }
    173         return super.getItemViewType(position);
    174     }
    175 
    176     @Override
    177     public int getViewTypeCount() {
    178         return VIEW_TYPE_COUNT;
    179     }
    180 
    181     @Override
    182     public int getCount() {
    183         return items != null ? items.size() : 0;
    184     }
    185 
    186     @Override
    187     public Object getItem(int position) {
    188         if (items != null && position > 0 && position < items.size()) {
    189             return items.get(position);
    190         }
    191         return null;
    192     }
    193 
    194     @Override
    195     public long getItemId(int postion) {
    196         return postion;
    197     }
    198 }

    至此,一个带有分栏的音乐列表制作完成。

    存在的问题:

    查询音乐列表是使用的排序方式为DEFAULT_SORT_ORDER,歌曲名为英文或特殊字符的歌曲会排在中文歌曲之后,而以上的分栏依赖歌曲的

    排序,所以会出现先对中文分组,再对英文分组的情况。我的想法是可以通过建立一张数据库表(包含使用pinYin4j生成的sortKey字段),将歌曲

    信息读入,然后查询时根据sortKey排序,这样中文和英文就能正确分组了(有时间再去实现一下^_^)。

    转载于:https://www.cnblogs.com/virtual-young/p/4124773.html

    展开全文
  • 【WORD】小论文如何正确添加注脚...我使用的是word2016,小论文的常规布局如下:中英文的标题、作者、摘要、关键词不分栏,正文内容分栏。 需求 我这里的需求是,保持正文内容分栏,在首页的底部,增加一个不分栏的...
  • 三种不同样式的分栏控制器。包括点击后移动滑块效果。选中后变色。选中内容放大效果 相关类定义 LXDSegmentControlConfiguration 用来配置分栏控制器的显示属性 LXDSegmentControl 分栏控制器 类型枚举 ...
  • 计算机基础与程序设计-要点分栏1-1-操作系统包括:1单用户操作系统,DOS;2批处理操作系统;3分时操作系统,UNIX,VMS;4实时操作系统时操作系统,VsWorks;5网络操作系统,netware;6分布式操作系统,MDS,CDCS;二、系统...
  • 用简单的例子说明了HTML页面的分栏,并且给出了简单的例子使得链接的页面用各种不同方式显示出来
  • 报表分栏后的排序

    2012-04-11 18:46:00
    可是新的问题又随之出现,分栏报表有一定的局限性,对于每栏中的数据无法进行排序,如果单单使用多个select的方式展现,又会被左主格的问题所困扰,所以变相的通过主子表的方式来实现。 例如实际需求中: 一张报表...
  • 等高分栏布局小结

    2016-02-01 09:32:00
    上一篇文章《圣杯布局小结》总结了几种常见的分栏布局方法,这几个方法都可以实现多栏页面下,所有栏的高度可动态变化,某一栏宽度自适应的布局效果,能满足工作中很多布局需求。后来我在搜集更多关于分栏布局的文章...
  • 分栏布局非常特殊,有别于传统布局方法,它将包括包括所有子元素在内的所有内容拆分为列,这与我们打印网页时候时页面内容分割成不同的页面的方式类似。 分栏布局IE10+都可以使用,API稳定,移动端兼容性比flex布局...
  • 2 同一页面上能否实现不同分栏块? 3 能否实现跨页分栏? 4 能否实现栏中栏? 5 分栏与打字的先后顺序?先选文字后分栏和先分栏后打字。 6 分栏后的段落调整技巧有哪些? 7 如何给纵向...
  • 关于分栏控制器问题

    2015-07-03 09:22:04
    1、分栏控制器基本概念 ·UITabBarController的基本概念 ·UITabBarController和UINavigationController一样是用来管理视图控制器的。 ·UINavigationController是用来管理视图控制器之间的导航,...
  • 设置页眉时先调整好页面布局大小,要和期刊要求一致,然后在页眉设计中的【位置】里可以设置页眉距离顶端和底端的距离,若有奇偶页不同需求,可在【选项】中设置 页脚 页脚与页眉操作相同,可以采用插入页码的...
  • 分栏控制器的基本概念和用法

    千次阅读 2014-06-07 17:09:09
    1、分栏控制器基本概念 ·UITabBarController的基本概念 ·UITabBarController和UINavigationController一样是用来管理视图控制器的。 ·UINavigationController是用来管理视图控制器之间的导航,...
  • 学生在用Word 2000对一篇文档进行排版时,用到了“分栏排版”功能,相同的操作步骤对文档不同段落进行“分栏排版”时,结果却大相径庭,问题就出现在文档的最后一段。下面我把操作过程和出现的结果说明一下: 1. ...
  • MySQL常用操作分栏整理 1.数据库的基本操作: 启动数据库:net start mysql 客户端登录服务器:mysql -u root -p 远程登录服务器:mysql -h ip地址 -u root -p 展示服务器中有哪些数据库:show databases; 创建一个...
  • 网页分栏设计写网页的时候,我们可能觉得自己做出来的东西和真正的网页有所差别,总是“少了点什么”。这很有可能是因为我们的网页没有注意分栏哦。这里是天猫主页的截图,大家可以观察一下它的分栏设计。右上角是...
  • 上一篇我们讲了登录页面的简单实现,其实在开发开发过程中,我们会经常使用到分栏控制器,也就是iOS中的UITabBarController。先给大家看一下效果图。 其实实现这个效果很简单,下面我依旧使用代码的方式来讲解 ...
  • 1、如何分栏和分节? 在进行论文撰写时,摘要题目等是一栏,而正文内容要分为两栏,此时就要进行页面分栏的操作。具体步骤如下: 首先选中摘要等内容,依次点击 布局——>分栏——>一栏,即可完成设置。接着...
  • /*取消先前通过registerDataSetObserver(DataSetObserver)方式注册进该适配器中的观察者对象*/ @Override public void unregisterDataSetObserver (DataSetObserver observer) { } /*获取组的个数*/ @...
  • 导航控制器 分栏控制器 在Vaadin中,要更改屏幕上显示的组件,有几个选项。 最直接的方法是在UI上使用setContent()方法。 最普遍的方法是使用导航器 。 导航器管理的视图会自动获得一个不同的URI,可用于标记视图...
  • drupal 页面分栏 当您在线发布任何内容时,布局内容的方式可能与内容本身一样重要。 良好的布局可以帮助读者更好地进行交互并使用该内容。 诸如Drupal之类的内容管理系统的用户有许多选择,可让他们创建非常吸引人...
  • 窗体界面,窗体框架,属性页功能,窗体分割框架,左右分栏================================我希望做的程序就是左边是个tree,然后我点不同的节点,在右边的主区域显示不同的内容,请问右边怎么做好呢?是用几个panel吗...
  • GTK+图形化应用程序开发学习笔记(十八)—滚动窗口构件、分栏窗口构件 一、滚动窗口构件滚动窗口构件(GtkScrolledWindow)用于创建一个可滚动区域,并将其他构件放入其中。可以在滚动窗口中插入任何其他构件,在其...
  • 1.多列(分栏) ​ 1)column-count 规定元素应该被分隔的列数(栏数)。 ​ column-count: number|auto; ​ 2)column-gap 设置栏间距。 ​ column-gap: length|normal; ​ 3)column-rule 设置栏间分隔线。 ​ a)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,004
精华内容 2,001
关键字:

不同的分栏方式