转载请标明出处:

http://blog.csdn.net/lmj623565791/article/details/46405409

本文出自:【张鸿洋的博客】

一、概述

Google I/O 2015 给大家带来了Android Design Support Library。对于希望做md风格的app的来说,简直是天大的喜讯了~大家能够通过Android Design Support Library该文章对其进行了解,也能够直接在github上下载演示样例代码执行学习。为了表达我心中的喜悦,我决定针对该库写一系列的文章来分别介绍新添加的控件。

ok,那么首先介绍的就是NavigationView。

注意下更新下as的SDK,然后在使用的过程中,在build.gradle中加入:

compile 'com.android.support:design:22.2.0'

在md风格的app中,比如例如以下风格的側滑菜单非经常见:

在之前的设计中。你可能须要考虑怎样去布局实现,比如使用ListView;再者还要去设计Item的选中状态之类~~

but,如今。google提供了NavigationView,你只须要写写布局文件。这种效果就ok了,而且兼容到Android 2.1。非常值得去体验一下。

接下来我们来介绍怎样去使用这个NavigationView

二、使用

使用起来very simple ,主要就是写写布局文件~

(一)布局文件

<?xml version="1.0" encoding="utf-8"?

>
<android.support.v4.widget.DrawerLayout
android:id="@+id/id_drawer_layout"
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:fitsSystemWindows="true"
> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.v7.widget.Toolbar
android:id="@+id/id_toolbar"
android:layout_width="match_parent"
android:layout_height="? attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> <TextView
android:id="@+id/id_tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="HelloWorld"
android:textSize="30sp"/>
</RelativeLayout> <android.support.design.widget.NavigationView
android:id="@+id/id_nv_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:fitsSystemWindows="true"
app:headerLayout="@layout/header_just_username"
app:menu="@menu/menu_drawer"
/> </android.support.v4.widget.DrawerLayout>

能够看到我们的最外层是DrawerLayout。里面一个content。一个作为drawer。我们的drawer为NavigationView

注意这个view的两个属性app:headerLayout="@layout/header_just_username"app:menu="@menu/menu_drawer",分别代表drawer布局中的header和menuitem区域。当然你能够依据自己的情况使用。

接下来看看header的布局文件和menu配置文件:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:background="?attr/colorPrimaryDark"
android:orientation="vertical"
android:padding="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark"> <TextView
android:id="@+id/id_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"
android:text="http://blog.csdn.net/lmj623565791"/> <TextView
android:id="@+id/id_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/id_link"
android:text="Zhang Hongyang"/> <ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_above="@id/id_username"
android:layout_marginBottom="16dp"
android:src="@mipmap/icon"/> </RelativeLayout>
<?

xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_dashboard"
android:title="Home"/>
<item
android:id="@+id/nav_messages"
android:icon="@drawable/ic_event"
android:title="Messages"/>
<item
android:id="@+id/nav_friends"
android:icon="@drawable/ic_headset"
android:title="Friends"/>
<item
android:id="@+id/nav_discussion"
android:icon="@drawable/ic_forum"
android:title="Discussion"/>
</group> <item android:title="Sub items">
<menu>
<item
android:icon="@drawable/ic_dashboard"
android:title="Sub item 1"/>
<item
android:icon="@drawable/ic_forum"
android:title="Sub item 2"/>
</menu>
</item> </menu>

别放错目录哈~

布局文件写完了,基本就好了,是不是非常爽~看似复杂的效果,写写布局文件就ok。

ps:默认的颜色非常多是从当前的主题中提取的。比方icon的stateColor,当然你也能够通过以下属性改动部分样式:

app:itemIconTint=""
app:itemBackground=""
app:itemTextColor=""

(二)Activity

最后是Activity:

package com.imooc.testandroid;

import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem; public class NavigationViewActivity extends ActionBarActivity
{ private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView; @Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation_view); mDrawerLayout = (DrawerLayout) findViewById(R.id.id_drawer_layout);
mNavigationView = (NavigationView) findViewById(R.id.id_nv_menu); Toolbar toolbar = (Toolbar) findViewById(R.id.id_toolbar);
setSupportActionBar(toolbar); final ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true); setupDrawerContent(mNavigationView); } private void setupDrawerContent(NavigationView navigationView)
{
navigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener()
{ @Override
public boolean onNavigationItemSelected(MenuItem menuItem)
{
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
return true;
}
});
} @Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_navigation_view, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getItemId() == android.R.id.home)
{
mDrawerLayout.openDrawer(GravityCompat.START);
return true ;
}
return super.onOptionsItemSelected(item);
} }

我们在Activity里面能够通过navigationView去navigationView.setNavigationItemSelectedListener,当selected的时候。menuItem去setChecked(true)。

别忘了设置theme~

<resources>

    <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style> <style name="Theme.DesignDemo" parent="Base.Theme.DesignDemo">
</style> <style name="Base.Theme.DesignDemo" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#673AB7</item>
<item name="colorPrimaryDark">#512DA8</item>
<item name="colorAccent">#FF4081</item>
<item name="android:windowBackground">@color/window_background</item>
</style> </resources> <color name="window_background">#FFF5F5F5</color> <activity
android:name=".NavigationViewActivity"
android:label="@string/title_activity_navigation_view"
android:theme="@style/Theme.DesignDemo">
</activity>

ok。到此就搞定了~~

不过存在一个问题,此时你假设点击Sub items里面的Sub item,假设你期望当前选中应该是Sub item。你会发现不起作用。那怎么办呢?

(三)Sub Item支持Cheable

这里能够改动menu的配置文件:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group>
<item
android:id="@+id/nav_home"
android:checkable="true"
android:icon="@drawable/ic_dashboard"
android:title="Home"/>
<item
android:id="@+id/nav_messages"
android:checkable="true"
android:icon="@drawable/ic_event"
android:title="Messages"/>
<item
android:id="@+id/nav_friends"
android:checkable="true"
android:icon="@drawable/ic_headset"
android:title="Friends"/>
<item
android:id="@+id/nav_discussion"
android:checkable="true"
android:icon="@drawable/ic_forum"
android:title="Discussion"/>
</group> <item android:title="Sub items">
<menu>
<item
android:checkable="true"
android:icon="@drawable/ic_dashboard"
android:title="Sub item 1"/>
<item
android:checkable="true"
android:icon="@drawable/ic_forum"
android:title="Sub item 2"/>
</menu>
</item> </menu>

android:checkableBehavior="single"去掉,然后给每一个item项加入android:checkable="true"

然后在代码中:

navigationView.setNavigationItemSelectedListener(

                new NavigationView.OnNavigationItemSelectedListener()
{ private MenuItem mPreMenuItem; @Override
public boolean onNavigationItemSelected(MenuItem menuItem)
{
if (mPreMenuItem != null) mPreMenuItem.setChecked(false);
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
mPreMenuItem = menuItem;
return true;
}
});

存一下preMenuItem。手动切换。

效果:

ok,哈~事实上这个还是參考链接2里面的一个评论说的~~

到此使用方法就介绍完了有木有一点小激动~ 可是还有个问题。对于app,就像ActionBar最初的出现,一開始大家都欢欣鼓励,后来发现app中多数情况下须要去定制,尼玛。是不是忽然认为ActionBar太死板了,恶心死了(当然了如今有了ToolBar灵活度上好多了)对于上述NavigationView可能也会存在定制上的问题。比方我希望选中的Item左边有个高亮的竖线之类的效果。

那么,针对于各种需求,想要能解决各种问题,最好的方式就是说对于NavigationView的效果自己能够实现。

最好,我们就来看看NavigationView自己实现有多难?

三、自己实现NavigationView效果

事实上NavigationView的实现非常easy,一个ListView就能够了。甚至都不须要去自己定义,简单写一个Adapter即可了~~

首先观察该图,有没有发现奇妙之处。恩,你肯定发现不了,由于我们做的太像了。

事实上这个图就是我通过ListView写的一个~是不是和原版非常像(~哈~參考了源代码的实现,当然像。)

接下来分析。假设说是ListView,那么Item的type肯定不止一种,那我们数一数种类:

  • 带图标和文本的
  • 不过文本的 Sub Items
  • 切割线

你会说还有顶部那个。顶部是headview呀~~

这么分析完毕,是不是瞬间认为没有难度了~

(一)首先布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/id_drawer_layout"
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:fitsSystemWindows="true"
> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.v7.widget.Toolbar
android:id="@+id/id_toolbar"
android:layout_width="match_parent"
android:layout_height="? attr/actionBarSize"
android:background="? attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> <TextView
android:id="@+id/id_tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="HelloWorld"
android:textSize="30sp"/>
</RelativeLayout> <ListView
android:id="@+id/id_lv_left_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:paddingTop="0dp"
android:background="#ffffffff"
android:clipToPadding="false"
android:divider="@null"
android:listSelector="?attr/selectableItemBackground"
/> </android.support.v4.widget.DrawerLayout>

布局文件上:和上文对照,我们只把NavigationView换成了ListView.

以下注意了,一大波代码来袭.

(二) Activity

package com.imooc.testandroid;

public class NavListViewActivity extends ActionBarActivity
{
private ListView mLvLeftMenu;
private DrawerLayout mDrawerLayout; @Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav_list_view); mDrawerLayout = (DrawerLayout) findViewById(R.id.id_drawer_layout);
mLvLeftMenu = (ListView) findViewById(R.id.id_lv_left_menu); Toolbar toolbar = (Toolbar) findViewById(R.id.id_toolbar);
setSupportActionBar(toolbar); final ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true); setUpDrawer();
} private void setUpDrawer()
{
LayoutInflater inflater = LayoutInflater.from(this);
mLvLeftMenu.addHeaderView(inflater.inflate(R.layout.header_just_username, mLvLeftMenu, false));
mLvLeftMenu.setAdapter(new MenuItemAdapter(this));
} @Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_nav_list_view, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == android.R.id.home)
{
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
} return super.onOptionsItemSelected(item);
} }

直接看onCreate中的setUpDrawer(),能够看到我们首先去addHeadView。然后去setAdapter。

那么核心代码就是我们的Adapter了~~

(三)MenuItemAdapter



    public class LvMenuItem
{
public LvMenuItem(int icon, String name)
{
this.icon = icon;
this.name = name; if (icon == NO_ICON && TextUtils.isEmpty(name))
{
type = TYPE_SEPARATOR;
} else if (icon == NO_ICON)
{
type = TYPE_NO_ICON;
} else
{
type = TYPE_NORMAL;
} if (type != TYPE_SEPARATOR && TextUtils.isEmpty(name))
{
throw new IllegalArgumentException("you need set a name for a non-SEPARATOR item");
} L.e(type + ""); } public LvMenuItem(String name)
{
this(NO_ICON, name);
} public LvMenuItem()
{
this(null);
} private static final int NO_ICON = 0;
public static final int TYPE_NORMAL = 0;
public static final int TYPE_NO_ICON = 1;
public static final int TYPE_SEPARATOR = 2; int type;
String name;
int icon; } public class MenuItemAdapter extends BaseAdapter
{
private final int mIconSize;
private LayoutInflater mInflater;
private Context mContext; public MenuItemAdapter(Context context)
{
mInflater = LayoutInflater.from(context);
mContext = context; mIconSize = context.getResources().getDimensionPixelSize(R.dimen.drawer_icon_size);//24dp
} private List<LvMenuItem> mItems = new ArrayList<LvMenuItem>(
Arrays.asList(
new LvMenuItem(R.drawable.ic_dashboard, "Home"),
new LvMenuItem(R.drawable.ic_event, "Messages"),
new LvMenuItem(R.drawable.ic_headset, "Friends"),
new LvMenuItem(R.drawable.ic_forum, "Discussion"),
new LvMenuItem(),
new LvMenuItem("Sub Items"),
new LvMenuItem(R.drawable.ic_dashboard, "Sub Item 1"),
new LvMenuItem(R.drawable.ic_forum, "Sub Item 2")
)); @Override
public int getCount()
{
return mItems.size();
} @Override
public Object getItem(int position)
{
return mItems.get(position);
} @Override
public long getItemId(int position)
{
return position;
} @Override
public int getViewTypeCount()
{
return 3;
} @Override
public int getItemViewType(int position)
{
return mItems.get(position).type;
} @Override
public View getView(int position, View convertView, ViewGroup parent)
{
LvMenuItem item = mItems.get(position);
switch (item.type)
{
case LvMenuItem.TYPE_NORMAL:
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.design_drawer_item, parent,
false);
}
TextView itemView = (TextView) convertView;
itemView.setText(item.name);
Drawable icon = mContext.getResources().getDrawable(item.icon);
setIconColor(icon);
if (icon != null)
{
icon.setBounds(0, 0, mIconSize, mIconSize);
TextViewCompat.setCompoundDrawablesRelative(itemView, icon, null, null, null);
} break;
case LvMenuItem.TYPE_NO_ICON:
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.design_drawer_item_subheader,
parent, false);
}
TextView subHeader = (TextView) convertView;
subHeader.setText(item.name);
break;
case LvMenuItem.TYPE_SEPARATOR:
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.design_drawer_item_separator,
parent, false);
}
break;
} return convertView;
} public void setIconColor(Drawable icon)
{
int textColorSecondary = android.R.attr.textColorSecondary;
TypedValue value = new TypedValue();
if (!mContext.getTheme().resolveAttribute(textColorSecondary, value, true))
{
return;
}
int baseColor = mContext.getResources().getColor(value.resourceId);
icon.setColorFilter(baseColor, PorterDuff.Mode.MULTIPLY);
}
}

首先我们的每一个Item相应于一个LvMenuItem。包括icon、name、type。能够看到我们的type分为3类。

那么adapter中代码就非常easy了,多Item布局的写法。

这样就完毕了,我们自己去书写NavigationView,是不是非常easy~~假设你的app须要相似效果,可是又与NavigationView的效果并不是一模一样。能够考虑依照上面的思路自己写一个。

最后贴一下用到的Item的布局文件:

  • design_drawer_item_subheader.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="? attr/listPreferredItemHeightSmall"
android:gravity="center_vertical|start"
android:maxLines="1"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="? attr/listPreferredItemPaddingRight"
android:textAppearance="? attr/textAppearanceListItem"
android:textColor="?android:textColorSecondary"/>
  • design_drawer_item_separator.xml

<? xml version="1.0" encoding="utf-8"? >
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <View android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"/> </FrameLayout>
  • design_drawer_item,xml:
<?

xml version="1.0" encoding="utf-8"?

>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:drawablePadding="32dp"
android:gravity="center_vertical|start"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="? android:attr/textColorPrimary"/>

ok。事实上上述ListView的写法也正是NavigationView的源代码实现~~item的布局文件直接从源代码中拖出来的,还是爽爽哒~

源代码点击下载

~~hava a nice day ~~

新浪微博

微信公众号:hongyangAndroid

(欢迎关注,第一时间推送博文信息)

參考链接

Android 自己实现 NavigationView [Design Support Library(1)]的更多相关文章

  1. Android Design Support Library(二)用NavigationView实现抽屉菜单界面

    NavigationView在MD设计中非常重要,之前Google也提出了使用DrawerLayout来实现导航抽屉.这次,在Android Design Support Library中,Googl ...

  2. Android Design Support Library初探,NavigationView实践

    前言 在前几天的IO大会上,Google带来了Android M,同时还有Android支持库的新一轮更新,其中更是增加一个全新的支持库Android Design Support Library,包 ...

  3. Android Design Support Library使用详解

    Android Design Support Library使用详解 Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的And ...

  4. 【转】【翻】Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

    转自:http://mrfufufu.github.io/android/2015/07/01/Codelab_Android_Design_Support_Library.html [翻]Andro ...

  5. 【转】Android的材料设计兼容库(Design Support Library)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0531/2958.html?mType=Group Android的材料设计兼容 ...

  6. Android应用Design Support Library完全使用实例

    阅读目录 2-1 综述 2-2 TextInputLayout控件 2-3 FloatingActionButton控件 2-4 Snackbar控件 2-5 TabLayout控件 2-6 Navi ...

  7. Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

    原文:Codelab for Android Design Support Library used in I/O Rewind Bangkok session--Make your app fanc ...

  8. Codelab for Android Design Support Library used in I/O Rewind Bangkok session

    At the moment I believe that there is no any Android Developer who doesn't know about Material Desig ...

  9. Material Design 开发利器:Android Design Support Library 介绍

    转自:https://blog.leancloud.cn/3306/ Android 5.0 Lollipop 是迄今为止最重大的一次发布,很大程度上是因为 material design —— 这是 ...

随机推荐

  1. [置顶] ※数据结构※→☆线性表结构(queue)☆============队列 顺序存储结构(queue sequence)(八)

    队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的 ...

  2. 深入研究Clang(四) Clang编译器的简单分析

    作者:史宁宁(snsn1984) 首先我们确定下Clang编译器的详细内容和涵盖范围.之前在<LLVM每日谈之二十 Everything && Clang driver>中 ...

  3. Swift - 环形进度条(UIActivityIndicatorView)的用法

    Swift中,除了条形进度条外,还有环形进度条,效果图如下: 1,环形进度条的基本属性 (1)Style: Large White:比较大的白色环形进度条 White:白色环形进度条 Gray:灰色环 ...

  4. struts2对action中的方法进行输入校验---xml配置方式(3)

    上面两篇文章已经介绍了通过编码java代码的方式实现action方法校验,这里我们介绍第二种方式:xml配置文件 首先我们来看一个样例: ValidateAction.java: package co ...

  5. 重复数据删除(De-duplication)技术研究(SourceForge上发布dedup util)

    dedup util是一款开源的轻量级文件打包工具,它基于块级的重复数据删除技术,可以有效缩减数据容量,节省用户存储空间.目前已经在Sourceforge上创建项目,并且源码正在不断更新中.该工具生成 ...

  6. Windows环境下访问NFS(33篇Storage的文章)

    Windows环境下访问NFS 使用Solaris时,如果想在两台Solaris之间共享数据,那么你想到的最省事.最方便的方法肯定是nfs.但是现在的学生们的桌面,估计99%以上都是Windows,W ...

  7. jquery ajax验证用户名是否存在(后台spring mvc)

    controller层 @ResponseBody @RequestMapping(value = "/user/isExist", produces = "applic ...

  8. Greenplum同步到Oracle

    开发提出须要从Greenplum同步到Oracle的解决方式,写了个脚本用于定时调度处理. #!/bin/sh #copy_gp_2_ora.sh if [ $# -ne 1 ]; then     ...

  9. 基于Linux根据僵尸网络病毒平台《比尔盖茨》

    感觉分析的非常好,所以决定翻译出来,希望和大家多多交流O(∩_∩)O~ 转载请注明出处:http://blog.csdn.net/u010484477     O(∩_∩)O谢谢 keyword:病毒 ...

  10. codeforces 598B Queries on a String

    题目链接:http://codeforces.com/problemset/problem/598/B 题目分类:字符串 题意:给定一个串,然后n次旋转,每次给l,r,k,表示区间l到r的字符进行k次 ...