精华内容
下载资源
问答
  • 最近,项目经理分配的一个任务是:要求根据不同角色身份的用户设计不用的登录界面,同时,用户不能跨登录界面登录。原话,我忘记了,意思是:比如,管理员只能用管理员登录界面登录,普通用户只能用普通用户登录界面...

    开发思路

    最近,项目经理分配的一个任务是:要求根据不同角色身份的用户设计不用的登录界面,同时,用户不能跨登录界面登录。原话,我忘记了,意思是:比如,管理员只能用管理员登录界面登录,普通用户只能用普通用户登录界面的登录。因为,我们的项目,登录时,shiro会对请求进行拦截,并根据绑定的realm完成校验… …现在我就根据代码详细的说明,如果有说错的地方,希望能不吝赐教。


    Filter

    请求被authc拦截,如果状态未登录,就会被跳到登录页面,登录成功后,会继续原请求页面,除非原请求就是successurl,才去successurl
    
    /**
     * 表单验证(包含验证码)过滤类
     * @author jeeplus
     * @version 2014-5-19
     */
    @Service
    public class EmployeeAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
    	
    
    	public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
    	public static final String DEFAULT_MOBILE_PARAM = "mobileLogin";
    	public static final String DEFAULT_MESSAGE_PARAM = "message";
    	private SystemService systemService;
    	
    	private String captchaParam = DEFAULT_CAPTCHA_PARAM;
    	private String mobileLoginParam = DEFAULT_MOBILE_PARAM;
    	private String messageParam = DEFAULT_MESSAGE_PARAM;
    
    	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
    		String username = getUsername(request);
    		String password = getPassword(request);
    		if (password==null){
    			password = "";
    		}
    		boolean rememberMe = isRememberMe(request);
    		String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
    		String captcha = getCaptcha(request);
    		boolean mobile = isMobileLogin(request);
    		String loginType = "user";
    		return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile,loginType);
    	}
    	/**
    	 * 获取系统业务对象
    	 */
    	public SystemService getSystemService() {
    		if (systemService == null){
    			systemService = SpringContextHolder.getBean(SystemService.class);
    		}
    		return systemService;
    	}
    
    	public String getCaptchaParam() {
    		return captchaParam;
    	}
    
    	protected String getCaptcha(ServletRequest request) {
    		return WebUtils.getCleanParam(request, getCaptchaParam());
    	}
    	
    	
    
    	public String getMobileLoginParam() {
    		return mobileLoginParam;
    	}
    	
    	protected boolean isMobileLogin(ServletRequest request) {
            return WebUtils.isTrue(request, getMobileLoginParam());
        }
    	
    	public String getMessageParam() {
    		return messageParam;
    	}
    	
    	/**
    	 * 登录成功之后跳转URL
    	 */
    	public String getSuccessUrl() {
    		return super.getSuccessUrl();
    	}
    	
    	@Override
    	protected void issueSuccessRedirect(ServletRequest request,
    			ServletResponse response) throws Exception {
    		Principal p = UserUtils.getPrincipal();
    		if (p != null && !p.isMobileLogin()){
    			 WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
    		}else{
    			//super.issueSuccessRedirect(request, response);//手机登录
    			AjaxJson j = new AjaxJson();
    			j.setSuccess(true);
    			j.setMsg("登录成功!");
    			j.put("username", p.getLoginName());
    			j.put("name", p.getName());
    			j.put("mobileLogin", p.isMobileLogin());
    			j.put("JSESSIONID", p.getSessionid());
    			PrintJSON.write((HttpServletResponse)response, j.getJsonStr());
    		}
    	}
    
    	/**
    	 * 登录失败调用事件
    	 */
    	@Override
    	protected boolean onLoginFailure(AuthenticationToken token,
    			AuthenticationException e, ServletRequest request, ServletResponse response) {
    		String className = e.getClass().getName(), message = "";
    		if (IncorrectCredentialsException.class.getName().equals(className)
    				|| UnknownAccountException.class.getName().equals(className)){
    			message = "用户或密码错误, 请重试.";
    		}
    		else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
    			message = StringUtils.replace(e.getMessage(), "msg:", "");
    		}
    		else{
    			message = "系统出现点问题,请稍后再试!";
    			e.printStackTrace(); // 输出到控制台
    		}
            request.setAttribute(getFailureKeyAttribute(), className);
            request.setAttribute(getMessageParam(), message);
            return true;
    	}
    	
    }
    

    由于代码比较多,我尽量粘贴全,以保证各位能够有清晰的了解;我会对主要的代码进行解释,其余的就不在过多叙述了。在输入完登录信息后,当我们点击登录,首先,Filter会进行过滤,首先,优先创建一个token(方法是:createToken),相信各位应该都能看懂,不过在此我要解释一下,loginType是我继承org.apache.shiro.authc.UsernamePasswordToken 然后新增的一个属性,因为,我要对不同页面进行辨别,这里,注意,因为我是两个登录页面,所以就需要两个Filter进行分别过滤,但是两者代码几乎相同,唯一不同的就是loginType=“admin”(loginType=“user”),所以就不粘贴了。

    	/**
     * 自定义认证器
     * 
     * @author Sunny
     */
    public class LoginRealmAuthenticator extends ModularRealmAuthenticator {
    	
    	private Map<String,Object> definedRealms;
    	private SystemService systemService;
    	
    	public void setDefinedRealms(Map<String, Object> definedRealms) {
    		this.definedRealms = definedRealms;
    	}
    	
    	/**
    	 * 获取系统业务对象
    	 */
    	public SystemService getSystemService() {
    		if (systemService == null){
    			systemService = SpringContextHolder.getBean(SystemService.class);
    		}
    		return systemService;
    	}
    	
    	/**
    	 * 根据用户类型判断使用哪个Realm
    	 */
    	@Override
    	protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)
    			throws AuthenticationException {
    		super.assertRealmsConfigured();
    		Realm realm = null;
    		// 使用自定义Token
    		UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
    		// 判断用户类型
    		if ("admin".equals(token.getLoginType())) {
    			realm = (Realm) this.definedRealms.get("systemAuthorizingRealm");
    		} else if ("user".equals(token.getLoginType())) {
    			realm = (Realm) this.definedRealms.get("loginAuthorizingRealm");
    		}
    		return this.doSingleRealmAuthentication(realm, authenticationToken);
    	}
    }
    

    当创建完token后,shiro就会通过认证器(至于为什么会这样,因为,是我配置文件这么配置的),这代码逻辑就比较简单了,就是根据loginType去选择所对应的realm,就不过多解释了。

    /**
     * 系统安全认证实现类
     * @author jeeplus
     * @version 2014-7-5
     */
    @Service
    //@DependsOn({"userDao","roleDao","menuDao"})
    public class LoginAuthorizingRealm extends AuthorizingRealm {
    
    	private Logger logger = LoggerFactory.getLogger(getClass());
    	
    	private SystemService systemService;
    	
    	@Autowired
    	HttpServletRequest request;
    
    	/**
    	 * 认证回调函数, 登录时调用
    	 */
    	@Override
    	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
    		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
    		
    		int activeSessionSize = getSystemService().getSessionDao().getActiveSessions(false).size();
    		if (logger.isDebugEnabled()){
    			logger.debug("login submit, active session size: {}, username: {}", activeSessionSize, token.getUsername());
    		}
    		
    		boolean mobile = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_MOBILE_PARAM);
    		// 校验登录验证码
    		if (!mobile && LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
    			Session session = UserUtils.getSession();
    			String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
    			if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
    				throw new AuthenticationException("msg:验证码错误, 请重试.");
    			}
    		}
    		
    		// 校验用户名密码
    		User user = getSystemService().getUserByLoginName(token.getUsername());
    		if (user != null) {
    			if (Global.NO.equals(user.getLoginFlag())){
    				throw new AuthenticationException("msg:该已帐号禁止登录.");
    			}
    			if("1".equals(user.getUserType())||"2".equals(user.getUserType())) {
    				throw new AuthenticationException("msg:只能普通用户登录.");
    			}
    			byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
    			return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()), 
    					user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
    		} else {
    			return null;
    		}
    	}
    
    	/**
    	 * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
    	 */
    	@Override
    	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    		Principal principal = (Principal) getAvailablePrincipal(principals);
    		// 获取当前已登录的用户
    		if (!Global.TRUE.equals(Global.getConfig("user.multiAccountLogin"))){
    			Collection<Session> sessions = getSystemService().getSessionDao().getActiveSessions(true, principal, UserUtils.getSession());
    			if (sessions.size() > 0){
    				// 如果是登录进来的,则踢出已在线用户
    				if (UserUtils.getSubject().isAuthenticated()){
    					for (Session session : sessions){
    						getSystemService().getSessionDao().delete(session);
    					}
    				}
    				// 记住我进来的,并且当前用户已登录,则退出当前用户提示信息。
    				else{
    					UserUtils.getSubject().logout();
    					throw new AuthenticationException("msg:账号已在其它地方登录,请重新登录。");
    				}
    			}
    		}
    		User user = getSystemService().getUserByLoginName(principal.getLoginName());
    		if (user != null) {
    			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    			List<Menu> list = UserUtils.getMenuList();
    			for (Menu menu : list){
    				if (StringUtils.isNotBlank(menu.getPermission())){
    					// 添加基于Permission的权限信息
    					for (String permission : StringUtils.split(menu.getPermission(),",")){
    						info.addStringPermission(permission);
    					}
    				}
    			}
    			// 添加用户权限
    			info.addStringPermission("user");
    			// 添加用户角色信息 
    			for (Role role : user.getRoleList()){
    				info.addRole(role.getEnname());
    			}
    			// 更新登录IP和时间
    			getSystemService().updateUserLoginInfo(user);
    			// 记录登录日志
    			LogUtils.saveLog(Servlets.getRequest(), "系统登录");
    			return info;
    		} else {
    			return null;
    		}
    	}
    	
    	@Override
    	protected void checkPermission(Permission permission, AuthorizationInfo info) {
    		authorizationValidate(permission);
    		super.checkPermission(permission, info);
    	}
    	
    	@Override
    	protected boolean[] isPermitted(List<Permission> permissions, AuthorizationInfo info) {
    		if (permissions != null && !permissions.isEmpty()) {
                for (Permission permission : permissions) {
            		authorizationValidate(permission);
                }
            }
    		return super.isPermitted(permissions, info);
    	}
    	
    	@Override
    	public boolean isPermitted(PrincipalCollection principals, Permission permission) {
    		authorizationValidate(permission);
    		return super.isPermitted(principals, permission);
    	}
    	
    	@Override
    	protected boolean isPermittedAll(Collection<Permission> permissions, AuthorizationInfo info) {
    		if (permissions != null && !permissions.isEmpty()) {
                for (Permission permission : permissions) {
                	authorizationValidate(permission);
                }
            }
    		return super.isPermittedAll(permissions, info);
    	}
    	
    	/**
    	 * 授权验证方法
    	 * @param permission
    	 */
    	private void authorizationValidate(Permission permission){
    		// 模块授权预留接口
    	}
    	
    	/**
    	 * 设定密码校验的Hash算法与迭代次数
    	 */
    	@PostConstruct
    	public void initCredentialsMatcher() {
    		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(SystemService.HASH_ALGORITHM);
    		matcher.setHashIterations(SystemService.HASH_INTERATIONS);
    		setCredentialsMatcher(matcher);
    	}
    	
    //	/**
    //	 * 清空用户关联权限认证,待下次使用时重新加载
    //	 */
    //	public void clearCachedAuthorizationInfo(Principal principal) {
    //		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
    //		clearCachedAuthorizationInfo(principals);
    //	}
    
    	/**
    	 * 清空所有关联认证
    	 * @Deprecated 不需要清空,授权缓存保存到session中
    	 */
    	@Deprecated
    	public void clearAllCachedAuthorizationInfo() {
    //		Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
    //		if (cache != null) {
    //			for (Object key : cache.keys()) {
    //				cache.remove(key);
    //			}
    //		}
    	}
    
    	/**
    	 * 获取系统业务对象
    	 */
    	public SystemService getSystemService() {
    		if (systemService == null){
    			systemService = SpringContextHolder.getBean(SystemService.class);
    		}
    		return systemService;
    	}
    	
    }
    

    经过认证器验证后,就会找到所对应的Realm,这时,就要执行doGetAuthenticationInfo方法,对登录用户信息进行验证了,首要对非手机登录和验证码登录进行判断,若是,则校验验证码是否正确;然后,通过用户的loginName获取用户信息,若不为空,就对密码进行加密并与数据库中加密密码比较,若,一致,则返回到Filter中,issueSuccessRedirect该方法就代表的校验成功时,会跳转到配置文件中定义的成功界面去;若,校验失败,就到Filter的onLoginFailure中,然后返回Controller定义的失败方法中,将失败信息返回给前端。
    配置文件:

    <!-- Shiro权限过滤过滤器定义 -->
    	<bean name="shiroFilterChainDefinitions" class="java.lang.String">
    		<constructor-arg>
    			<value>
    				/static/** = anon
    				/userfiles/** = anon
    				${adminPath}/sys/user/infoCareStatus = anon
    				${adminPath}/sys/user/validateLoginName = anon
    				${adminPath}/sys/user/validateMobile = anon
    				${adminPath}/sys/user/validateMobileExist = anon
    				${adminPath}/sys/user/resetPassword = anon
    				${adminPath}/sys/register = anon
    				${adminPath}/sys/register/registerUser = anon
    				${adminPath}/sys/register/getRegisterCode = anon
    				${adminPath}/sys/register/validateMobileCode = anon
    				${adminPath}/soft/sysVersion/getAndroidVer = anon
    				${adminPath}/soft/sysVersion/getIosVer = anon
    				${adminPath}/cas = cas
    				${adminPath}/login = authc
    				${adminPath}/loginEmployee = membersAuthc
    				${adminPath}/logout = anon
    				${adminPath}/** = user
    				/act/rest/service/editor/** = perms[act:model:edit]
    				/act/rest/service/model/** = perms[act:model:edit]
    				/act/rest/service/** = user
    				/ReportServer/** = user
    			</value>
    		</constructor-arg>
    	</bean>
    	
    <bean id="membersAuthc"
    		class="com.jeeplus.modules.sys.security.EmployeeAuthenticationFilter">
    		<property name="loginUrl" value="${adminPath}/loginEmployee" />
    		<property name="successUrl" value="${adminPath}?loginEmployee" />
    	</bean>
    
    	
    	<!-- 安全认证过滤器 -->
    	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    		<property name="securityManager" ref="securityManager" /><!-- 
    		<property name="loginUrl" value="${cas.server.url}?service=${cas.project.url}${adminPath}/cas" /> -->
    		<property name="loginUrl" value="${adminPath}/login" />
    		<property name="successUrl" value="${adminPath}?login" />
    		<property name="filters">
                <map>
                    <entry key="cas" value-ref="casFilter"/>
                    <entry key="authc" value-ref="formAuthenticationFilter"/>
                    <entry key="membersAuthc" value-ref="membersAuthc"/>
                </map>
            </property>
    		<property name="filterChainDefinitions">
    			<ref bean="shiroFilterChainDefinitions"/>
    		</property>
    	</bean>
    	<bean id="definedRealms" class="org.springframework.beans.factory.config.MapFactoryBean">
            <property name="sourceMap">
                <map>
                    <entry key="systemAuthorizingRealm" value-ref="systemAuthorizingRealm"/>
                    <entry key="loginAuthorizingRealm" value-ref="loginAuthorizingRealm" />
                </map>
            </property>
    
        </bean>
    
    	
    	<bean id="loginRealmAuthenticator" class="com.jeeplus.modules.sys.security.LoginRealmAuthenticator">
    	    <property name="definedRealms" ref="definedRealms"/> 
    	</bean>
    	
    	<!-- 定义Shiro安全管理配置 -->
    	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    		<property name="authenticator" ref="loginRealmAuthenticator" />
    		<property name="realms">
    		<list>
    			<ref bean="systemAuthorizingRealm" />
    			<ref bean="loginAuthorizingRealm" />
    		</list>
    	</property>
    		<property name="sessionManager" ref="sessionManager" />
    		<property name="cacheManager" ref="shiroCacheManager" />
    	</bean>
    

    配置文件只是将登录Shiro认证的主要配置写在这里。
    web.xml就不在这里贴了,但是,请别忘记将shiroFilter过滤器配置进去,否则,就是,无用功了。

    离线写博客

    这篇博客要感谢https://blog.csdn.net/z947511564/article/details/52261546?utm_source=itdadao&utm_medium=referral作者以及https://blog.csdn.net/mn1992602/article/details/73527889/作者等等,我是参考了众多博客楼主的思路,在结合我自己项目的实际需求,完成开发的,技术永远就是分享就是进步。

    展开全文
  • 手机软件界面设计

    千次阅读 2008-06-18 14:36:00
    手机软件界面设计 界面的说法以往常见的是在人机工程学中。"人机界面"是指人机间相互施加影响的区域,凡参与人机信息交流的一切领域都属于人机界面。"而设计艺术是研究人一物关系的学科,对象物所代表的不是简单的...
    手机软件界面设计   界面的说法以往常见的是在人机工程学中。"人机界面"是指人机间相互施加影响的区域,凡参与人机信息交流的一切领域都属于人机界面。"而设计艺术是研究人一物关系的学科,对象物所代表的不是简单的机器与设备,而是有广度与深度的物;这里的人也不是"生物人",不能单纯地以人的生理特征进行分析。"人的尺度,既应有作为自然人的尺度,还应有作为社会人的尺度;既研究生理、心理、环境等对人的影响和效能,也研究人的文化、审美、价值观念等方面的要求和变化"。      设计的界面存在于人一物信息交流,甚至可以说,存在人物信息交流的一切领域都属于设计界面,它的内涵要素是极为广泛的。可将设计界面定义为设计中所面对、所分析的一切信息交互的总和,它反映着人一物之间的关系。   设计界面的存在      美国学者赫伯特.A.西蒙提出:设计是人工物的内部环境(人工物自身的物质和组织)和外部环境(人工物的工作或使用环境)的接合。所以设计是把握人工物内部环境与外部环境接合的学科,这种接合是围绕人来进行的。"人"是设计界面的一个方面,是认识的主体和设计服务的对象,而作为对象的"物"则是设计界面的另一个方面。它是包含着对象实体、环境及信息的综合体,就如我们看见一件产品、一栋建筑,它带给人的不仅有使用的功能、材料的质地,也包含着对传统思考、文化理喻、科学观念等的认知。"任何一件作品的内容,都必须超出作品中所包含的那些个别物体的表象。"分析"物"也就分析了设计界面存在的多样性。      为了便于认识和分析设计界面,可将设计界面分类为: 1)功能性设计界面接受物的功能信息,操纵与控制物,同时也包括与生产的接口,即材料运用、科学技术的应用等等。这一界面反映着设计与人造物的协调作用。      2)情感性设计界面即物要传递感受给人,取得与人的感情共鸣。这种感受的信息传达存在着确定性与不确定性的统一。情感把握在于深入目标对象的使用者的感情,而不是个人的情感抒发。设计师"投入热情,不投入感情",避免个人的任何主观臆断与个性的自由发挥。这-界面反映着设计与人的关系。      3)环境性设计界面外部环境因素对人的信息传递。任何一件或一个产品或平面视觉传达作品或室内外环境作品都不能脱离环境而存在,环境的物理条件与精神氛围是不可忽缺的界面因素。      应该说,设计界面是以功能性界面为基础,以环境性界面为前提,以情感性界面为重心而构成的,它们之间形成有机和系统的联系。   设计界面存在的方法论意义     当机械大工业发展起来的时候,如何有效操纵和控制产品或机械的问题导致了人机工程学。二战后,随着体力的简单劳动转向脑力的复杂劳动,人体工学也进一步地扩大到人的思维能力的设计方面,"使设计能够支持、解放、扩展人的脑力劳动"。在目前的知识经济时代,在满足了物质需求的情况下,人们追求自身个性的发展和情感诉求,设计必须要着重对人的情感需求进行考虑。设计因素复杂化导致设计评价标准困难化。一个个性化的设计作品能否被消费者所认同?新产品开发能不能被市场所接受?在目前,我国大部分企业实力还并不强大,设计开发失利承受力还不很强的情况下,如何系统地、有根据地认识、评价设计,使其符合市场,就需要对设计因素再认识。利用界面分析法,正是使设计因素条理化,避免将人作为"生物人"的片面和走出笼统地说"设计=科学十艺术"的简单误区。      现代的人机工程学和消费心理学为设计提供了科学的依据,它们的成功就在于实验、调查和数理表述,是较为可系的。同样对设计艺术而言,进行设计界面的分析,也要有生理学、心理学、文化学、生物学、技术学学科基础。从理论上来说,它要直接建立在信息论和控制论的基础之上。相对于机械、电子设计和人机设计,以往人机界面设计把握了技术科学的认识和手段,忽视了人文科学观念与思想。它的界面设计只能存在于局部的思考范围内,只成为一个设计的阶段。      有人以功能论来评判设计。"功能决定形态"曾是20世纪上半叶的设计格言,它的提法是片面的。这是因为:第一,功能不是单一的,它包括使用功能、审美功能、社会功能、环境功能等。"过分追求单一的功能会导致将许多重要内容(装饰性、民族性、中间性)被排斥掉"。而且"有些内容并不是'功能'的概念所能包括了的,更何况物质和精神的内容也并不是时时处处等质等量的融洽在一个统一体中,随产品的不同、时期的不同,它们各自的主次地位也随之变化"。在现今信息技术高度发展的时代,情感因素越来越成为设计的主要方面。物质意义上的功能在保持其基础地位的情况下,却日益不能代表情感诉求的表述;第二,按"形态服从功能"而设计的产品,对于不熟悉它的使用者来说是难以理解的,产品要为人们所理解,必须要借助公认的信码,即符号系统;第三,满足同一功能的产品形态本来就不是唯一的,象汽车等成熟的产品,年度换型计划等措施成为商品经济中日益不可避免的现象。社会经济发展到一定程度,才能出现设计的专业需求,而这时人们的基本物质需求已能满足,简单地以物质性功能来决定设计是不恰当的。      相反,设计界面体现了人一物交流信息的本质,也是设计艺术的内涵,它包括了设计的方方面面,明确了设计的目标与程序。   设计界面的分析      按照设计界面的三类划分,有助于考察设计界面的多种因素。当然,应该说设计界面的划分是不可能完全绝对的,三类界面之间有涵义上也可能交互与重叠,如宗教文化是一种环境性因素,但它带给信仰者的往往更多的却是宗教的情感因素。在这里环境性和情感性是不好区分的,但这并不妨碍不同分类之间所存在的实质性的差异。      1 功能性界面 对功能性界面来说,它实现的是使用性内容,任何'件产品或内外环境或平面视觉传达作品,其存在的价值首要的是在于使用性,由使用性牵涉到多种功能因素的分析及实现功能的技术方法与材料运用。在这一方面,分析思维作为一种理性思维而存在。如果作为一种处理方式来设计产品,则这种产品会使多种特征性(如民族性、纯粹性)因素中性化,如果去除产品商标,就很难认出是哪国的或哪个公司的产品。当然,这方面也说明了产品中存在着共同性因素,它使全人类能做出同样的反应。人的感觉和判断能力有着国际性的、客观性的特征。      功能性界面设计要建立在符号学的基础上。国际符号学会对符号学所下定义是:符号是关于信号标志系统(即通过某种渠道传递信息的系统)的理论,它研究自然符号系统和人造符号系统的特征。广义的说,能够代表其他事物的东西都是符号,如字母、数字、仪式、意识、动作等,最复杂的一种符号系统可能就是语言。设计功能界面,不可避免地要让使用者明白功能操作。每一操作对人来说应是符合思维逻辑的,是人性的,而对机械、电子来说则应是准确的、确定无疑的,这双方的信息传递是功能界面的核心内涵。      2 情感性界面 一个家庭装饰要赋予人家居的温馨,一副平面作品要以情动人,一件宗教器具要体现信仰者的虔诚。其实任何一件产品或作品只有与人的情感产生共鸣才能为人所接受,"敝帚自珍"正体现着人的感情寄托,也体现着设计作品的魅力所在。      现代符号学的发展也日益这一领域开拓,以努力使这种不确定性得到压缩,部分加强理性化成分。符号学逐渐应用于民俗学、神话学、宗教学、广告学等领域,如日本符号学界把符号学用于认识论研究,考察认识知觉、认识过程的符号学问题。同时,符号学还用于分析利用人体感官进行的交际,并将音乐、舞蹈、服装、装饰等都作为符号系统加以分析研究,这都为设计艺术提供了宝贵与有借鉴价值的情感界面设计方法与技术手段。      3 环境性界面 任何的设计都要与环境因素相联系,它包括社会、政治和文化等综合领域。处于外界环境之中,"是以社会群体而不是以个体为基础的",所以环境性因素一般处于非受控与难以预见的变化状态。      联系到设计的历史,我们可以利用艺术社会学的观点去认识各时期的设计潮流。18世纪起,西方一批美学家已注意到艺术创造与审美趣味深受地理、气候、民族、历史条件等环境因素的影响。法国实证主义哲学家孔德指出:"文学艺术是人的创造物,原则上是由创造它的人所处的环境条件决定。"法国文艺理论家丹纳认为"物质文明与精神文明的性质面貌都取决于种族、环境、时代三大因素"。无论是工艺美术运动、包豪斯现代主义或20世纪80年代的反设计,现代的多元化,"游牧主义"(Nemadism)都反映着环境因素的影响。      环境性界面设计所涵盖的因素是极为广泛的,它包括有政治、历史、经济、文化、科技、民族等,这方面的界面设计正体现了设计艺术的社会性。      以上说明了设计艺术界面存在的特征因素,说明在理性与非理性上都存在明确、合理、有规则、有根据的认识方法与手段。      成功的作品都是完善地处理了这三个界面的结晶。如贝聿铭设计的卢浮宫扩建工程,功能性处理得很好,没有屈从于形式而损害功能;但同时又通过新材料及形式反映新的时代性特征及美学倾向,这是环境性界面处理的典范;人们观看卢浮宫,不是回到古代,而是以新的价值观去重新审视、欣赏,它的三角形外观符合了人们的心理期望,这是情感性界面处理的极致。     设计界面的运用原则      1)合理性原则,即保证在系统设计基础上的合理与明确。    任何的设计都既要有定性也要有定量的分析,是理性与感性思维相结合。努力减少非理性因素,而以定量优化、提高为基础。设计不应人云亦云,一定要在正确、系统的事实和数据的基础上,进行严密地理论分析,能以理服人、以情感人。      2)动态性原则,即要有四维空间或五维空间的运作观念。一件作品不仅是二维的平面或三绝的立体,也要有时间与空间的变换,情感与思维认识的演变等多维因素。      3)多样化原则,即设计因素多样化考虑。当前越来越多的专业调查人员与公司出现,为设计带来丰富的资料和依据。但是,如何获取有效信息,如何分析设计信息实际上是一个要有创造性思维与方法的过程体系。      4)交互性原则,即界面设计强调交互过程。一方面是物的信息传达,另一方面是人的接受与反馈,对任何物的信息都能动地认识与把握。      5)共通性原则,即把握三类界面的协调统一,功能、情感、环境不能孤立而存在。       的应用方法      设计界面所包含的因素是极为广泛的,但在运用中却只能有侧重、有强调的把握。设计因素虽多,但它仍是一个不可分割的整体。它的结果是物化的形,但这个形却是代表了时代、民族等方面的意识,并最终反映出人的"美"的心理活动。      设计界面的运用,核心是设计分析。在一些国际性的大公司,如索尼、松下、柯尼卡等,都有许多的成功案例可为借鉴。如柯尼卡公司设计其相机时,首先不是去绘制"美"的形和考虑技术的进步,而是进行对象人的日常行为分析,作出故事版(STORY)。它先假定对象人的年龄为35岁,名:Xxxx,从而分析他的家庭、喜好与憎恶,分析他的日常行为,进而考察其人在什么场合需要僚机,从而为设计提供概念(CONCEPT)与目标(TARGET),进行设计。经过分析,设计师有了明确的概念与目标,并随信息的交互产生了创造力。      另一方面,设计师自身对社会环境也要进行深入的认识与考察,对设计的作品取向有明晰的认识:是否符合人们的消费预期?是否能感受到人们的审美知觉?日本设计师佐野邦雄先生曾作一图--生活的变迁与设计师的课题,将日本及世界上某些非常有影响性的事件,如技术的进步、企业的发展等等都进行了归纳,进而对设计有了深入的认识与感悟。      所以,要运用好设计的界面,理性的认识是首要的,其次就是创造性的,而且是有实效性的分析、处理信息。设计不是一成不变的,分析方法也不是一成不变的,设计的界面同样是在人一物   UI界面设计流程 人类社会逐步向非物质社会迈进,互联网信息产业已经走入我们的生活。在这样一个非物质社会中,网站与软件这些非物质产品再也不象过去那样紧紧靠技术就能处于不败之地。工业设计开始关注非物质产品。但是在国内依然普遍存在这样一个称呼"美工"。"工"的意思就是没有思想紧紧靠体力工作的人。这是一个很愚昧的做法,愚昧在于称呼职员美工的企业没有意识到界面与交互设计能给他们带来的巨大经济效益,另一方面愚昧在于被称为美工的人不知道自己应该做什么,以为自己的工作就是每天给界面与网站勾边描图。     本文主要讲述一套比较科学的设计流程来讲述UI界面设计属于工业设计的范畴,是一个科学的设计过程,理性的商业运作模式。而不是单纯的美术描边。     UI的本意是user interface也就是用户与界面的关系。他包括交互设计,用户研究,与界面设计 三个部分。本文主要讲述用户研究与界面设计的过程。   一个通用消费类软件界面的设计大体可分为五个步骤:     需求阶段 分析设计阶段 调研验证阶段 方案改进阶段 用户验证反馈阶段需求阶段     软件产品依然属于工业产品的范畴。依然离不开3W的考虑(Who,where,why.)也就是使用者,使用环境,使用方式的需求分析。所以在设计一个软件产品之前我们应该明确什么人用(用户的年龄,性别,爱好,收入,教育程度等)。什么地方用(在办公室/家庭/厂房车间/公共场所)。如何用(鼠标键盘/遥控器/触摸屏)。上面的任何一个元素改变结果都会有相应的改变。     除此之外在需求阶段同类竞争产品也是我们必须了解的。同类产品比我们提前问世,我们要比他作的更好才有存在的价值。那么单纯的从界面美学考虑说哪个好哪个不好是没有一个很客观的评价标准的。我们只能说哪个更合适,更合适于我们的最终用户的就是最好的。如何判定最合适于用户呢,后面我会介绍用户调研。       分析设计阶段     通过分析上面的需求,我们进入设计阶段。也就是方案形成阶段。我们设计出几套不同风格的界面用于被选。首先我们应该制作一个体现用户定位的词语坐标。例如我们为25岁左右的白领男性制作家居娱乐软件。对于这类用户我们分析得到的词汇有:品质,精美,高档,高雅,男性,时尚,cool,,个性,亲和,放松等。分析这些词汇的时候我们会发现有些词是绝对必须体现的,例如:品质,精美,高档,时尚。但有些词是相互矛盾的,必须放弃一些,例如:亲和,放松与 cool,个性与等。所以我们画出一个坐标,上面是我们必须用的品质,精美,高档,时尚。左边是贴近用户心理的词汇:亲和,放松,人性化。右边是体现用户外在形象的词汇:cool,个性,工业化。然后我们开始搜集相呼应的图片,放在坐标的不同点上。这样根据不同作标点的风格,我们设计出数套不同风格的界面。     调研验证阶段     几套风格必须保证在同等的设计制作水平上,不能明显看出差异,这样才能得到用户客观的反馈。     测试阶段开始前我们应该对测试的具体细节进行清楚的分析描述。       例如:      数据收集方式:厅堂测试/模拟家居/办公室。      测试时间:X年X月X日X日。      测试区域:北京、广州、天津。     测试对象。某消费软件界定市场用户。主要特征为:     对电脑的硬件配置以及相关的性能指标比较了解,电脑应用水平较高; 电脑使用经历一年以上;   家庭购买电脑时品牌和机型的主要决策者   年龄:X-X岁;   年龄在X岁以上的被访者文化程度为大专及以上;   个人月收入X以上或家庭月收入X元及以上;   样品     五套软件界面     样本量:X个,实际完成X个。       调研阶段需要从以下几个问题出发:     用户对各套方案的第一印象 用户对各套方案的综合印象 用户对各套方案的单独评价 选出最喜欢的 选出其次喜欢的 对各方案的色彩,文字,图形等分别打分。 结论出来以后请所有用户说出最受欢迎方案的优缺点。     所有这些都需要用图形表达出来,直观科学。     方案改进阶段     经过用户调研,我们得到目标用户最喜欢的方案。而且了解到用户为什么喜欢,还有什么遗憾等,这样我们就可以进行下一步修改了。这时候我们可以把精力投入到一个方案上(这里指不能换皮肤的应用软件或游戏的界面)将方案做到细致精美。     用户验证阶段     改正以后的方案,我们可以将他推向市场。但是设计并没有结束。我们还需要用户反馈,好的设计师应该在产品上市以后去站柜台。零距离接触最终用户,看看用户真正使用时的感想。为以后的升级版本积累经验资料。     经过上面设计过程的描述,大家可以清楚的发现,界面UI设计是一个非常科学的推导公式,他有设计师对艺术的理解感悟,但绝对不是仅仅表现设计师个人的绘画。所以我们一再强调这个工作过程是设计过程。UI界面设计不存在美工。   五、UI设计的一般工作流程   (取自某UI设计服务公司)   1)熟悉行业(熟悉您的软件所涉及的行业,以便制作出适合行业特征的界面风格)   2)了解软件(了解您软件的工程进度,做出针对您进度的工作计划)。   3)与软件开发工程师和市场人员讨论界面风格(广泛听取研发和市场人员的意见,做出 最适合市场的软件)。   4)人机分析(对您的软件进行人机分析,增强您软件的易用性)。   5)做方案(做出设计方案,并明确细节思想)。   6)审定方案(与技术和市场人员一起审定方案,并听取修改意见)。   7)修改——审定(将有几次重复)   8)细化、制作界面(开始制作软件界面)。   9)与软件开发工程师合作把界面加入到程序中。   10)细部修改,完成。   11)进行软件包装盒、光盘盘面、盘套等的设计工作。   12)后期跟踪服务(在完成项目后,对您的软件进行跟踪服务,即对您软件从发布到推出新版本之间的小规模修改进行调整,包括对帮   软件界面设计要素   界面设计是为了满足软件专业化标准化的需求而产生的对软件的使用界面进行美化优化规范化的设计分支。具体包括软件启动封面设计,软件框架设计,按钮设计,面板设计,菜单设计,标签设计,图标设计,滚动条及状态栏设计,安装过程设计,包装及商品化。     在设计的过程中有较多注意的关键问题,以下列出几点:     (1)软件启动封面设计     应使软件启动封面最终为高清晰度的图像,如软件启动封面需在不同的平台、操作系统上使用将考虑转换不同的格式,并且对选用的色彩不宜超过256色,最好为216色安全色。软件启动封面大小多为主流显示器分辨率的1/6大。如果是系列软件将考虑整体设计的统一和延续性。在上面应该醒目的标注制作或支持的公司标志、产品商标,软件名称,版本号,网址,版权声明,序列号等信息,以树立软件形象,方便使用者或购买者在软件启动的时候得到提示。插图宜使用具有独立版权的,象征性强的,识别性高的,视觉传达效果好的图形,若使用摄影也应该进行数位处理,以形成该软件的个性化特征。     (2)软件框架设计     软件的框架设计就复杂得多,因为涉及软件的使用功能,应该对该软件产品的程序和使用比较了解,这就需要设计师有一定的软件跟进经验,能够快速的学习软件产品,并且在和软件产品的程序开发员及程序使用对象进行共同沟通,以设计出友好的,独特的,符合程序开发原则的软件框架。软件框架设计应该简洁明快,尽量少用无谓的装饰,应该考虑节省屏幕空间,各种分辨率的大小,缩放时的状态和原则,并且为将来设计的按钮,菜单,标签,滚动条及状态栏预留位置。设计中将整体色彩组合进行合理搭配,将软件商标放在显著位置,主菜单应放在左边或上边,滚动条放在右边,状态栏放在下边,以符合视觉流程和用户使用心理。     (3)软件按钮设计     软件按钮设计应该具有交互性,即应该有3到6种状态效果:点击时状态;鼠标放在上面但未点击的状态;点击前鼠标未放在上面时的状态;点击后鼠标未放在上面时的状态;不能点击时状态;独立自动变化的状态。按钮应具备简洁的图示效果,应能够让使用者产生功能关联反应,群组内按钮应该风格统一,功能差异大的按钮应该有所区别。     (4)软件面板设计     软件面板设计应该具有缩放功能,面板应该对功能区间划分清晰,应该和对话框,弹出框等风格匹配,尽量节省空间,切换方便。     (5)菜单设计     菜单设计一般有选中状态和未选中状态,左边应为名称,右边应为快捷键,如果有下级菜单应该有下级箭头符号,不同功能区间应该用线条分割。     (6)标签设计     标签设计应该注意转角部分的变化,状态可参考按钮。     (7)图标设计     图标设计色彩不宜超过64色,大小为16x16、32x32两种,图标设计是方寸艺术,应该加以着重考虑视觉冲击力,它需要在很小的范围表现出软件的内涵,所以很多图标设计师在设计图标时使用简单的颜色,利用眼睛对色彩和网点的空间混合效果,做出了许多精彩图标。     (8)滚动条及状态栏设计     滚动条主要是为了对区域性空间的固定大小中内容量的变换进行设计,应该有上下箭头,滚动标等,有些还有翻页标。状态栏是为了对软件当前状态的显示和提示。     (9)安装过程设计     安装过程设计主要是将软件安装的过程进行美化,包括对软件功能进行图示化。     (10)包装及商品化     最后软件产品的包装应该考虑保护好软件产品,功能的宣传融合于美观中,可以印刷部分产品介绍,产品界面设计   GOIDEA主要服务项目: 界面设计 企业海报设计,企业形象海报设计,企业产品海报设计,宣传海报设计,海报设计,直邮广告设计(DM),企业年报设计,型录设计,样本设计,折页设计,单页设计,宣传单设计,广告单设计,房地产楼书设计,通讯录设计,招标书设计包装设计等.     涵义      界面设计的说法以往常见的是在人机工程学中。"人机界面"是指人机间相互施加影响的区域,凡参与人机信息交流的一切领域都属于人机界面。"而设计艺术是研究人一物关系的学科,对象物所代表的不是简单的机器与设备,而是有广度与深度的物;这里的人也不是"生物人",不能单纯地以人的生理特征进行分析。"人的尺度,既应有作为自然人的尺度,还应有作为社会人的尺度;既研究生理、心理、环境等对人的影响和效能,也研究人的文化、审美、价值观念等方面的要求和变化"。      设计的界面存在于人一物信息交流,甚至可以说,存在人物信息交流的一切领域都属于设计界面,它的内涵要素是极为广泛的。可将设计界面定义为设计中所面对、所分析的一切信息交互的总和,它反映着人一物之间的关系。   存在      美国学者赫伯特.A.西蒙提出:设计是人工物的内部环境(人工物自身的物质和组织)和外部环境(人工物的工作或使用环境)的接合。所以设计是把握人工物内部环境与外部环境接合的学科,这种接合是围绕人来进行的。"人"是设计界面的一个方面,是认识的主体和设计服务的对象,而作为对象的"物"则是设计界面的另一个方面。它是包含着对象实体、环境及信息的综合体,就如我们看见一件产品、一栋建筑,它带给人的不仅有使用的功能、材料的质地,也包含着对传统思考、文化理喻、科学观念等的认知。"任何一件作品的内容,都必须超出作品中所包含的那些个别物体的表象。"分析"物"也就分析了设计界面存在的多样性。      为了便于认识和分析设计界面,可将设计界面分类为:    1)功能性设计界面接受物的功能信息,操纵与控制物,同时也包括与生产的接口,即材料运用、科学技术的应用等等。这一界面反映着设计与人造物的协调作用。      2)情感性设计界面即物要传递感受给人,取得与人的感情共鸣。这种感受的信息传达存在着确定性与不确定性的统一。情感把握在于深入目标对象的使用者的感情,而不是个人的情感抒发。设计师"投入热情,不投入感情",避免个人的任何主观臆断与个性的自由发挥。这-界面反映着设计与人的关系。      3)环境性设计界面外部环境因素对人的信息传递。任何一件或一个产品或平面视觉传达作品或室内外环境作品都不能脱离环境而存在,环境的物理条件与精神氛围是不可忽缺的界面因素。      应该说,设计界面是以功能性界面为基础,以环境性界面为前提,以情感性界面为重心而构成的,它们之间形成有机和系统的联系。   存在的方法论意义     当机械大工业发展起来的时候,如何有效操纵和控制产品或机械的问题导致了人机工程学。二战后,随着体力的简单劳动转向脑力的复杂劳动,人体工学也进一步地扩大到人的思维能力的设计方面,"使设计能够支持、解放、扩展人的脑力劳动"。在目前的知识经济时代,在满足了物质需求的情况下,人们追求自身个性的发展和情感诉求,设计必须要着重对人的情感需求进行考虑。设计因素复杂化导致设计评价标准困难化。一个个性化的设计作品能否被消费者所认同?新产品开发能不能被市场所接受?在目前,我国大部分企业实力还并不强大,设计开发失利承受力还不很强的情况下,如何系统地、有根据地认识、评价设计,使其符合市场,就需要对设计因素再认识。利用界面分析法,正是使设计因素条理化,避免将人作为"生物人"的片面和走出笼统地说"设计=科学十艺术"的简单误区。      现代的人机工程学和消费心理学为设计提供了科学的依据,它们的成功就在于实验、调查和数理表述,是较为可系的。同样对设计艺术而言,进行设计界面的分析,也要有生理学、心理学、文化学、生物学、技术学学科基础。从理论上来说,它要直接建立在信息论和控制论的基础之上。相对于机械、电子设计和人机设计,以往人机界面设计把握了技术科学的认识和手段,忽视了人文科学观念与思想。它的界面设计只能存在于局部的思考范围内,只成为一个设计的阶段。      有人以功能论来评判设计。"功能决定形态"曾是20世纪上半叶的设计格言,它的提法是片面的。这是因为:第一,功能不是单一的,它包括使用功能、审美功能、社会功能、环境功能等。"过分追求单一的功能会导致将许多重要内容(装饰性、民族性、中间性)被排斥掉"。而且"有些内容并不是'功能'的概念所能包括了的,更何况物质和精神的内容也并不是时时处处等质等量的融洽在一个统一体中,随产品的不同、时期的不同,它们各自的主次地位也随之变化"。在现今信息技术高度发展的时代,情感因素越来越成为设计的主要方面。物质意义上的功能在保持其基础地位的情况下,却日益不能代表情感诉求的表述;第二,按"形态服从功能"而设计的产品,对于不熟悉它的使用者来说是难以理解的,产品要为人们所理解,必须要借助公认的信码,即符号系统;第三,满足同一功能的产品形态本来就不是唯一的,象汽车等成熟的产品,年度换型计划等措施成为商品经济中日益不可避免的现象。社会经济发展到一定程度,才能出现设计的专业需求,而这时人们的基本物质需求已能满足,简单地以物质性功能来决定设计是不恰当的。      相反,设计界面体现了人一物交流信息的本质,也是设计艺术的内涵,它包括了设计的方方面面,明确了设计的目标与程序。   分析      按照设计界面的三类划分,有助于考察设计界面的多种因素。当然,应该说设计界面的划分是不可能完全绝对的,三类界面之间有涵义上也可能交互与重叠,如宗教文化是一种环境性因素,但它带给信仰者的往往更多的却是宗教的情感因素。在这里环境性和情感性是不好区分的,但这并不妨碍不同分类之间所存在的实质性的差异。      1 功能性界面    对功能性界面来说,它实现的是使用性内容,任何'件产品或内外环境或平面视觉传达作品,其存在的价值首要的是在于使用性,由使用性牵涉到多种功能因素的分析及实现功能的技术方法与材料运用。在这一方面,分析思维作为一种理性思维而存在。如果作为一种处理方式来设计产品,则这种产品会使多种特征性(如民族性、纯粹性)因素中性化,如果去除产品商标,就很难认出是哪国的或哪个公司的产品。当然,这方面也说明了产品中存在着共同性因素,它使全人类能做出同样的反应。人的感觉和判断能力有着国际性的、客观性的特征。      功能性界面设计要建立在符号学的基础上。国际符号学会对符号学所下定义是:符号是关于信号标志系统(即通过某种渠道传递信息的系统)的理论,它研究自然符号系统和人造符号系统的特征。广义的说,能够代表其他事物的东西都是符号,如字母、数字、仪式、意识、动作等,最复杂的一种符号系统可能就是语言。设计功能界面,不可避免地要让使用者明白功能操作。每一操作对人来说应是符合思维逻辑的,是人性的,而对机械、电子来说则应是准确的、确定无疑的,这双方的信息传递是功能界面的核心内涵。      2 情感性界面    一个家庭装饰要赋予人家居的温馨,一副平面作品要以情动人,一件宗教器具要体现信仰者的虔诚。其实任何一件产品或作品只有与人的情感产生共鸣才能为人所接受,"敝帚自珍"正体现着人的感情寄托,也体现着设计作品的魅力所在。      现代符号学的发展也日益这一领域开拓,以努力使这种不确定性得到压缩,部分加强理性化成分。符号学逐渐应用于民俗学、神话学、宗教学、广告学等领域,如日本符号学界把符号学用于认识论研究,考察认识知觉、认识过程的符号学问题。同时,符号学还用于分析利用人体感官进行的交际,并将音乐、舞蹈、服装、装饰等都作为符号系统加以分析研究,这都为设计艺术提供了宝贵与有借鉴价值的情感界面设计方法与技术手段。      3 环境性界面    任何的设计都要与环境因素相联系,它包括社会、政治和文化等综合领域。处于外界环境之中,"是以社会群体而不是以个体为基础的",所以环境性因素一般处于非受控与难以预见的变化状态。      联系到设计的历史,我们可以利用艺术社会学的观点去认识各时期的设计潮流。18世纪起,西方一批美学家已注意到艺术创造与审美趣味深受地理、气候、民族、历史条件等环境因素的影响。法国实证主义哲学家孔德指出:"文学艺术是人的创造物,原则上是由创造它的人所处的环境条件决定。"法国文艺理论家丹纳认为"物质文明与精神文明的性质面貌都取决于种族、环境、时代三大因素"。无论是工艺美术运动、包豪斯现代主义或20世纪80年代的反设计,现代的多元化,"游牧主义"(Nemadism)都反映着环境因素的影响。      环境性界面设计所涵盖的因素是极为广泛的,它包括有政治、历史、经济、文化、科技、民族等,这方面的界面设计正体现了设计艺术的社会性。      以上说明了设计艺术界面存在的特征因素,说明在理性与非理性上都存在明确、合理、有规则、有根据的认识方法与手段。      成功的作品都是完善地处理了这三个界面的结晶。如贝聿铭设计的卢浮宫扩建工程,功能性处理得很好,没有屈从于形式而损害功能;但同时又通过新材料及形式反映新的时代性特征及美学倾向,这是环境性界面处理的典范;人们观看卢浮宫,不是回到古代,而是以新的价值观去重新审视、欣赏,它的三角形外观符合了人们的心理期望,这是情感性界面处理的极致。
    展开全文
  • C语言多重密码进入不同...但是在用手机的时候发现了一个问题,现在大多数手机都可以用不同的指纹或者密码进入不同手机界面,也就是所谓的分身。这就让我有了灵感,如果我用C语言按着书上说的内容写一个多重密码...

    C语言多重密码进入不同界面

    原创:丶无殇            2018-7-16

    简介:

            作为小白的自己在学习的过程中,看到过书上的有关密码的一个章节。书上说的是设定一个密码,然后用户输入正确的密码进入需要的界面。但是在用手机的时候发现了一个问题,现在大多数手机都可以用不同的指纹或者密码进入不同的手机界面,也就是所谓的分身。这就让我有了灵感,如果我用C语言按着书上说的内容写一个多重密码出来,对于自己的学习会有所进步,也想把自己的想法写出来给大家看看,也冒昧的让大家给我一些指点,并且能够相互学习。


    单密码

            首先是单密码,顾名思义,就是单个密码,就像我们正常的,一个账号对应一个密码。这个属于比较简单的,便于大家初学者看得懂,毕竟我自己也是初学者,高深的用法也不会。

            这里用到的知识点就是:指针、循环结构、选择结构。

            我这里用的是中文的密码,如果想要用数字和字母组成的密码的话,也是可以的,只不过有些用法就稍微有点变化,这就需要我们初学者自己去发现了。

            单密码的原理比较简单:就是首先设定一个密码,保存在一个指针中。然后讲输入的内容也保存在一个指针中,将该指针与密码进行比较,相同则为正确,否则为错误。并且可以根据你是否想要继续尝试输入密码来控制是否跳出循环。下面是一个完整的代码:

    #include<stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main()
    {
        char *password = "你好";// 保存密码
        char *inputPs = (char *)malloc(64);// 保存输入的密码
        char ch;
        printf("请输入启动密码:");
        while(ch!='n')
        {
            gets(inputPs);
            if(strcmp(password, inputPs) == 0)
            {
                printf("密码正确!\n");
    			return 0;
    	}
            else
            {
                printf("密码错误,按回车重新输入!\n输入‘n’退出!");
    			scanf("%c",&ch);
            }
        }
    	printf("已退出该关卡!");
        return 0;
    }


    多重密码

            其次就是多重密码,这部分和单密码有所区别。我是用了结构体的知识,将密码存放在结构体成员列表中,方便后面调用对比。

            这部分用到的知识:结构体、指针、选择结构。

            这里同样是中文密码。

            我写这个多重密码的时候用的结构体,可能是个人喜好吧,其实也可以用一个一个单独赋值的方式,这里就不多说了。多重密码原理就是:将你输入的密码与结构体中的内容进行比较,对应的是界面一的密码,则进入界面一;如果是界面二的密码,则进入界面二;同理可以设置n多个界面密码。下面是完整代码:

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    struct password
    {
    	char pw1[64];
    	char pw2[64];
    };
    struct password pw={"你好","你很棒"};
    
    int main()
    {
    	char *input=(char *)malloc(64);
    	printf("\n\n\n\n%s\n\n\n",&pw.pw1);//仅用于测试结构体
    	gets(input);
    	if(strcmp(pw.pw1,input)==0)
    		printf("关卡1正确!\n");
    	else if(strcmp(pw.pw2,input)==0)
    		printf("关卡2正确!\n");
    	else 
    		printf("密码错误!");
    }


            最后再次申明,这篇文章是个人学习时候的一个想法,有不到之处希望得到指点。

            同时希望我的这篇文章能给大家带来一定的用处,谢谢阅读!


    展开全文
  • 使用rem等比例缩放手机界面

    千次阅读 2016-08-02 23:06:38
    这几天写公司官网的手机界面,同事介绍了一种布局模式,即使用rem等比列缩放布局。 rem布局非常简单,首页你只需在页面引入这段原生js代码就可以了。 (function (doc, win) { var docEl = doc.documentElement,...

    这几天写公司官网的手机端界面,同事介绍了一种布局模式,即使用rem等比列缩放布局。

    rem布局非常简单,首页你只需在页面引入这段原生js代码就可以了。

        (function (doc, win) {
            var docEl = doc.documentElement,
                resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
                recalc = function () {
                    var clientWidth = docEl.clientWidth;
                    if (!clientWidth) return;
                    if(clientWidth>=640){
                        docEl.style.fontSize = '100px';
                    }else{
                        docEl.style.fontSize = 100 * (clientWidth / 640) + 'px';
                    }
                };
    
            if (!doc.addEventListener) return;
            win.addEventListener(resizeEvt, recalc, false);
            doc.addEventListener('DOMContentLoaded', recalc, false);
        })(document, window);

    如何使用?

    这是rem布局的核心代码,这段代码的大意是:
    如果页面的宽度超过了640px,那么页面中html的font-size恒为100px,否则,页面中html的font-size的大小为: 100 * (当前页面宽度 / 640)
    于是,问题来了,为什么要这样?别急,我先来一一回答

    1. 为什么是640px?
      对于手机屏幕来说,640px的页面宽度是一个安全的最大宽度,保证了移动端页面两边不会留白。注意这里的px是css逻辑像素,与设备的物理像素是有区别的。如iPhone 5使用的是Retina视网膜屏幕,使用2px x 2px的 device pixel 代表 1px x 1px 的 css pixel,所以设备像素数为640 x 1136px,而它的CSS逻辑像素数为320 x 568px。
      如果要切移动端页面,你可以先把效果图宽度等比例缩放到640px,很好用。
    2. 为什么要设置html的font-size?
      rem就是根元素(即:html)的字体大小。html中的所有标签样式凡是涉及到尺寸的(如: height,width,padding,margin,font-size。甚至,left,top等)你都可以放心大胆的用rem作单位。
      如果你把html的font-size设为20px,前面说过,rem就是html的字体大小,那么1rem = 20px。
      此时,此时宽60px,高40px的元素样式就这样设置如下 ↓
      width: 3rem;
      height: 2rem;
      那要是宽55px,高37px呢?然后经过换算,,设置如下 ↓
      width: 2.75rem;
      height: 1.85rem;
      是不是发现这换算起来有点麻烦啊,,,(当然,你要是心算帝请无视)
      如果我们一开始把html的font-size设为100px呢?此时1rem = 100px,那么上面的宽55px,高37px的元素样式就可以这么设置 ↓
      width: 0.55rem;
      height: 0.37rem;
      是不是换算起来简单多了?!
      (当然可能有同学问,为什么不一开始把html的font-size设为1px呢,这样换算起来也简单,答:浏览器一般都有最小字体限制,比如谷歌浏览器,最小中文字体就是12px,所以实际上没有办法让1rem=1px。)
      根据上面的js代码,如果页面宽度低于640px,那么页面中html的font-size也会按照(当前页面宽度/640)的比例变化。这样,页面中凡是应用了rem的作尺寸单位的元素都会随着页面变化而等比例缩放了!
    3. 都哪些情况可以用rem布局?
      大部分情况下都可以用rem布局这个方法,当然具体还要看情况而定。拿我们公司项目举例,只有底部的导航不用rem,而是用的flex布局。因为导航点击最多,所以给它一个固定的大小(其实就是高度固定,宽度自适应的方案)。大家可以看看淘宝的这个手机页面淘宝手机站,基本就是这种感觉,底部导航和顶部搜索框用的高固定,宽自适应的方案,其余的部分基本都是随着浏览器宽度变化在等比例缩放。

    最终页面代码首页代码大致如下

    <!DOCTYPE html>
    <html lang="en">
    <head> 
     <meta charset="UTF-8">  
     <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">  
    <script>   
    (function (doc, win) {
            var docEl = doc.documentElement,
                resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
                recalc = function () {
                    var clientWidth = docEl.clientWidth;
                    if (!clientWidth) return;
                    if(clientWidth>=640){
                        docEl.style.fontSize = '100px';
                    }else{
                        docEl.style.fontSize = 100 * (clientWidth / 640) + 'px';
                    }
                };
    
            if (!doc.addEventListener) return;
            win.addEventListener(resizeEvt, recalc, false);
            doc.addEventListener('DOMContentLoaded', recalc, false);
        })(document, window);
    </script> 
     /*你引进的资源*/
    <title>标题</title> 
    </head>
    <body>
     /*你的代码*/
    </body>
    </html>

    回过头来再看看现在流行的几种布局方式:

    1.定宽度布局

    很多pc的网站都是定宽度布局的,也就是设置了min-width,

    这样一来,如果小于这个宽度就会出现滚动条,

    如果大于这个宽度则内容居中外加背景,

    这种设计常见与pc端。

    2.响应式布局

    所谓响应式布局就是流式布局+媒体查询,

    流式布局用来解决不同宽度的布局问题,

    外加媒体查询,可以调整布局,例如大屏幕是布局1,小屏幕是布局2,

    这种布局通吃pc和移动端,做到精细处,两者的效果都很好,

    缺点是媒体查询是有限的,也就是可以枚举出来的,

    只能适应主流的宽高。

    3.rem布局

    原理是,先按定高宽设计出来页面,然后转换为rem单位,

    配合js查询屏幕大小来改变html的font-size,

    最终做出所谓的完美自适应。


    4.flex布局

    这是css3 推出的一个新的属性。使用该属性可以很方便的达到布局的效果。使用该属性后,子元素不能再使用float、vertical-middle等属性。

    目前新的主流浏览器都支持该属性(IE10+上)。因此该布局用于手机端,表示毫无压力。

    详情可以查看http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool



    【rem缺点】

    rem一出好像所有移动端自适应不采用rem都很low一样,

    来分析分析,

    假设以100x100做出网页,

    那么采用rem+js完全可以自适应所有200x200,300x300,450x450等等高宽,


    问题来了,

    如果用100x100设计好后,

    来了100x200,100x300,100x400的手机,

    那么效果无非两种:

    1.网页内容只局限与网页顶部,例如100x400的手机,网页内容只占用的100x100的部分,

    2.有人说可以高度也js+rem,那么效果无非是拉伸或者缩放

    【不要抬杠】

    有人会说了,现实中不会有100x400的手机,

    我想说的是这种rem+js只不过是宽度自适应,

    高度没有做到自适应,一些对高度,或者元素见间距要求比较高的设计,

    那这种布局没有太大的意义。

    如果只是宽度自适应,那我更推荐的是响应式设计。


    【响应式 vs rem】

    1.响应式

    随便找一个响应式的网站:http://www.golaravel.com/

    改变浏览器宽度,你会发现“布局”会随之变化,不是一成不变的,

    例如导航栏在大屏幕下是横排,在小屏幕下是竖排,在超小屏幕下隐藏为菜单,

    也就是说如果有足够的耐心,在每一种屏幕下都应该有合理的布局,完美的效果。

    优点:适应pc和移动端,如果足够耐心,效果完美

    缺点:要匹配足够多的屏幕大小,工作量不小,设计也需要多个版本

    2.rem+js

    找了腾讯那篇文章的示例:http://121.40.99.17/global/rem-phone.html

    改变浏览器宽度,你会发现,页面所有元素的高宽都等比例缩放,

    也就是大屏幕下导航是横的,小屏幕下还是横的只不过变小了。。

    优点:理想状态是所有屏幕的高宽比和最初的设计高宽比一样,或者相差不多,完美适应。

    缺点:碰到重视高度的设计,或者重视元素间间距的设计,那就玩不开了。

    【总结】

    1.如果只做pc端

    那么定宽度是最好的选择

    2.如果做移动端,且设计对高度要求不高

    那么rem+js是最好的选择,一份css+一份js调节font-size搞定

    3.如果pc,移动要兼容,而且要求很高

    那么响应式布局还是最好的选择,前提是设计根据不同的高宽做不同的设计,

    响应式根据媒体查询做不同的布局。


    【ps】

    还有一种rem+媒体查询,和rem+js一对比感觉有点鸡肋就没有提及。


    参考:
    1:文/随意那天(简书作者)
    原文链接:http://www.jianshu.com/p/b00cd3506782
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    2:http://blog.csdn.net/uikoo9/article/details/46555751
    展开全文
  • 第一章 APP用户界面基础 1.1 手机UI设计相关基本概念 1.1.1 什么是UI设计 UI(User's Interface)即用户界面, ...它不仅仅是美化界面,还需要...1.1.2 手机UI与平面UI的不同 手机UI将范围基本锁定在手机的APP/客
  • 手机端web/app界面设计尺寸规范

    万次阅读 2018-06-08 13:21:07
    手机端web/app界面设计尺寸规范移动端高清、多屏适配方案背景开发移动端H5页面面对不同分辨率的手机面对不同屏幕尺寸的手机视觉稿在前端开发之前,视觉MM会给我们一个psd文件,称之为视觉稿。对于移动端开发而言,...
  • 不过与之前采用Android 2.3系统的MOTO机型不同,MOTO XT885 UI界面并未经过个性化设定,而是与ICS原生界面非常相似。能看出细微差别的是解锁、下拉状态区以及拍照界面等。▲ 手机运行Android 4.0...
  • 采用navigateBack的delta返回 , 有可能导致返回页面不一致 如:wx.navigateBack({  delta: 1  })   解决办法: ...var page = getCurrentPages() ;...var beforePage = page[page.length - 2];...
  • 界面手机和模拟器上显示的差异

    千次阅读 2007-12-29 13:06:00
    高通告诫我们:程序一定要... 反差最大的莫过于界面,第一次把程序拷到手机上,期望很大,也很自信,结果——惨不忍睹。 以下是我给大家的一些建议: 1.显示中文时,不要直接在屏幕上打印,把中文文字放在资源(ba
  • Android不同手机屏幕分辨率自适应

    万次阅读 2013-11-25 00:33:55
    有必要了解的 Android中常见的单位 dip, dp, px, sp之间的区别: dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个...
  • 1、手机网站的类型不同。...手机网站和电脑网站之间最大区别就分辨显示率不同,电脑屏幕尺寸要比手机屏幕尺寸大的多,所以在网站界面设计上就会不一样,手机网站版面相对要窄一点,字体尺寸一般...
  • 横竖屏和界面不同分辨率适配

    千次阅读 2018-12-03 15:27:30
    界面不同分辨率适配 不同的分辨率在同是竖屏的情况下,只有一个layout页面,如何用于不同的分辨率的屏幕呢,需要针对某些控件进行精准的长高设置,就需要根据不同分辨率添加不同的dimens文件 ,如添加一个1920*...
  • android Tv app界面呈现与mobile app 界面呈现的区别
  • Android手机分辨率基础知识(DPI,DIP计算)   1.术语和概念 术语 说明 备注 Screen size(屏幕尺寸) 指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7...
  • 在智能手机市场上苹果的iPhone 一直都有着很高的关注度,不过其高昂的价格却让人望而却步。有些年轻人为了拥有一部iPhone 不惜出租胸部来做广告位,更有甚者还卖身卖肾。其实这又何苦呢。现在市场上已经有了一款...
  • 嘿,哥们,我现在要iphone手机 通讯录里面搜索的样式,你搞定哦。。。。。。,要一毛一样哦。作为一个文化人,我只能在内心深处生 出表达出,苦逼的我们顶多发发牢骚,要改就改喽。 请看图先 这是他要的效
  • 我的第一个手机是Nokia 5110(1988年买的),它的功能非常少,所以我只用它来打打电话、玩玩贪食蛇。但是随着厂商不断的技术革新,传统手机使用方式被完全颠覆了。现在我们都在使用大尺寸的触屏手机,并且出现了...
  • android中不同手机分辨率适配问题 在项目开发的过程中,同一个布局对应不同的手机会显示出不同的效果。导致这个现象产生的原因是不同手机的分辨率不同。在android sdk提供的帮助文档中,我们可以看到各种手机的...
  • 用户界面

    千次阅读 2011-11-12 23:38:23
    用户界面 (2010-11-14 12:23:04) 标签: 校园 分类: 工作篇 有机界面研究的回顾与展望   演讲人:麻省理工学院计算机科学和人工智能研究中心主任 Victor Zue博士 会议:“二十一...
  • Android手机屏幕大小不一,有480x320, 640x360, 800x480.怎样才能让App自动适应不同的屏幕呢? 其实很简单,只需要在res目录下创建不同的layout文件夹,比如layout-640x360,layout-800x480,所有的layout文件在...
  • 之“用户界面和多媒体”版面 有价值问题的整理 历史 Version Date Creator Description 1.0.0.1 2006-4-4 郑昀 草稿 1.0.0.2 2006-4-6 ...
  • 软件界面设计思想方法

    万次阅读 2015-03-04 10:16:28
    15.1什么是好的软件界面 简而言之,好的软件界面应当是易用的和美观的。易用是交互设计的主要目标,美观是视觉设计的主要目标,交互设计和视觉设计完成后,最终靠编程来实现可运行的软件界面。 15.1.1易用 ...
  • 上一回说到,用户选择是否升级,若用户选择不升级,那么就要进入程序的主界面。下面要做的是从splash界面跳转到main界面。 MainActivity创建 1.首先新建MainActivity: package com.liuhao.mobilesafe.ui; import ...
  • 关于UI界面每个界面尺寸适配的问题

    千次阅读 2017-08-14 09:37:44
    界面名字 每个界面需定出一个前缀。比如主页,前缀是 home,设置前缀为 settings,课程表是 lesson。 定好前缀之后。设计师就可以建立文件夹: 主页(home) 设置(settings) 课程表(lesson) 课程概述(overview) 共用...
  • Android微信界面的设计

    千次阅读 2016-07-13 09:12:48
    Android微信界面的设计 微信主界面: (1)整体采用垂直的LinearLayout线性布局 (2)最上面是ActionBar,搜索框SearchView,Overflow(含有4个单选菜单项) (3)中间使用ViewPager+Fragment组件,这样可实现左右...
  • 手机设置———>开发者选项———–>开启显示布局边界,页面有布局的是native否则为h5页面; 长按页面,如果出现文字选择、粘贴功能的是H5页面,否则是native页面,我在我们自己的App里面试了一下是可以判断的。但是有...
  • Android应用界面布局

    千次阅读 2017-01-17 16:51:21
    Android的应用编写基本都会有一个界面,而Android应用的编写逻辑是遵循MVC模式的,它将界面和控制逻辑是分开的,这样一来,界面编写就和应用的业务逻辑是分开的,更改系统业务逻辑也无需改变前台界面,增强了应用的...
  • iOS界面跳转的一些优化方案

    千次阅读 2018-03-26 14:37:49
    App应用程序开发, 界面跳转是基础中的基础, 几乎没有一个App是用不到界面跳转的, 那么怎么样去书写界面跳转代码才是比较合理的呢? 大家可能在想跳转无非就2种方式, 能有什么内容? 其实并不是这样子的, 对于研发老手...
  • 前端客户端界面

    千次阅读 2020-05-24 12:03:14
    结构:指的是html 样式:指的是CSS 行为:指的是javascript 2、HTML4、XHTML和HTML5的区别? HTML4:格式语法等规范不明确,可以随意使用 XHTML:制定了规范,但是没有增加新的内容,不被程序员认可和使用 HTML5:...
  • 了解不同界面框架的优缺点3.能够根据产品需求设计界面框架前言我们说界面的框架设计不仅仅是UI同学的设计,更多的是产品经理和交互设计师的工作。为什么呢?因为我们的产品需求当确定之后,我们马上要做的共组就是对...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 58,947
精华内容 23,578
关键字:

不同手机界面的区别