当前位置: 主页 > 业界资讯
跳槽其实是需要勇气

跳槽其实是需要勇气

IT蓝豹|2016/3/1638 阅


很多人都想挑战高薪,可是每次要跳槽的时候又顾虑很多,担心自己技术没进步,在继续呆在当前公司弥补一下技术,或者是在准

备充足了在跳槽,其实这些都是理由,个人认为是看自己敢不敢挑战,因为新的一份工作有新的一份压力,看自己能否扛得住的问

题。


    最近很多android的小伙伴们都问我,自己想跳槽,但是又感觉android这个趋势已经在下滑了,工作不太好找,其实小伙

伴们想太多了,安卓近年行业发展不错,移动互联网时代带动安卓行业发展,安卓在未来5-10年间前景也比较乐观的,安卓行业也

是非常有前途的,未来发展趋势有很好的兆头,如下几点可以说明:
1、移动互联网时代到来,带动了安卓开发行业发展。安卓系统会越来越好的。
2、企业对相关安卓职位的人才招聘量比较大。因此安卓行业前景比较好,就业也非常好。
3、安卓的行业前景好薪酬待遇自然也是普遍较好的。只要好好学习安卓开发知识,可以成就高薪就业梦,甚至带动安卓爱好者的创

业梦!
4、安卓最大的优势就是开源,免费,对企业来说能节省很大成本,所以搞的比较多。


如果想学习android的朋友欢迎到 IT蓝豹 www.itlanbao.com一起学习android,IT蓝豹 一个专业的android技术分享平台,希望给

大家带来帮助。

面试时,哪些问题能试出一个Android应用开发者真正的水平?

面试时,哪些问题能试出一个Android应用开发者真正的水平?

IT蓝豹|2016/2/221427 阅

一般面试时间短则30分钟,多则1个小时,这么点时间要全面考察一个人难度很大,需要一些技巧,这里我不局限于回答题主的问题,而是分享一下我个人关于如何做好Android技术面试的一些经验,有什么问题都可以找我们技术大牛沟通。


面试前的准备


1. 简历调查


简历到你手上的时候,你要做好充分的调查分析,不仅仅是对公司负责,也是对自己与候选人时间的尊重,明显不match的简历,就不要抱着“要不喊过来试试看”的想法了,候选人也许很不错,但如果跟你的岗位不match,也不要浪费大家时间,你要想清楚现在需要的人是有潜力可以培养的,还是亟需帮忙干活的。另外如果简历里附带了博客链接,GitHub地址,相关作品的,可以提前去看看,直接看人家多年积累的文章与代码,比这短短一小时的面试来得靠谱的多。

2. 准备问题


了解清楚候选人背景后,要根据简历,有针对性的准备问题,可以是他作品或做过项目里的某个技术细节的实现方式,也可以是他声称精通的某些领域的相关问题。总之不要等到面试过程中现想问题,特别是刚开始面试别人的同学,往往经验不足稍带紧张导致大脑短路,其实也是很尴尬的,把要问的问题提前写下来,准备充分。

考察哪些点?


1. 简历是否真实


这其实是面试第一要务,面试的过程其实就是看简历是否属实的过程,因为能到面试环节,说明这个人是符合要求的,不满足要求的早就被剔除了,如果他真的如简历描述的那样,100%会招过来,如果人人都如此,那就不需要有面试这种过程了。


需要注意的是这里的真实有三层含义:


    一是他如实描述了自身经历,很多人只在一些大项目里做一个很小的螺丝钉,但简历里往往夸张这段经历。


    二是不知道自己不知道,常见于简历里各种“精通”开头的描述,因为知识体系与视野的局限,明明只是了解很浅却夸口精通,很多时候他并不认为自己说的有问题,而是真的以为自己已然精通,有点井底之蛙的感觉。


    三是简历里的真实要与你的期望相匹配,一门技术了解到怎样的程度才算精通,很难有定论,所以这里的“真实”只能是候选人与面试官标准之间的契合,这种有主观运气成分,也许面试官水平不够错误判断了你,也不用感到不爽,面试何尝不是种双向选择呢。


2. 技术的深度


技术的深度一向是我最看重的部分,当今任何一个技术领域都非常宽广,一个人要同时掌握那么多知识并且都深入几乎不可能,那都需要拼学习效率与工作年限了。而你曾经做过的东西,正在做的东西,是绝对可以了解得更深入的,一个对技术有好奇心,有技术热情的人,都不会仅仅停留在这个东西挺好用,而是会忍不住去探究它背后的技术原理,即便不是亲自去看源码,也会花点时间了解别人整理过的经验,所以单凭考察技术上的深度,就可以考察一个人是否对技术有热情,是否有技术好奇心等等这些很多大牛认为的所谓“优秀程序员的特征”。


之前曾看到过一句话:“一个人对他所做的事情了解得越深,他就能做的越好”。放在这里再合适不过了。


3. 技术的广度


深度是有了,还需要广度吗?我个人的理解是:深度是必要条件,广度是加分项。同样的有技术好奇心的优秀程序员,也不会满足于仅仅局限于自己的一亩三分地,工作之余,也会想要尝试一些其它的领域和方向,因为投入问题也许不够深入,但很多领域知识你知道与不知道,对你个人知识体系的形成关系很大。比如你要实现一个功能,在你当前熟悉的技术领域上很困难或者效果不佳,在你就要放弃时你的同事告诉你,这用一个简单sql语句就可以实现啦,为什么要搞得那么麻烦?这个例子虽然举得很蹩脚,但是我想意思大家应该已经明白了。知识越有广度,头脑里的技术体系就越完备,同样的问题,你就可以想到N个解,思考一下就得出最优解了,如果你听都没听过一些东西,就会经常说出“这个好难搞啊”,“这根本就不可能”,其实有的时候真是知识的局限问题,所谓的从0到1难,也是这个意思。


4. 逻辑思维能力


这也是我比较看重的一点,这里并不是指那些臭名昭彰的脑经急转弯问题,而是通过交流观察,判断一个人表达观点逻辑是否清晰,回答问题是否有章法,这个很难描述,但如果你细心观察,你会发现很容易通过一些简单的交流,就可以看出一个人是否逻辑清晰。有时候你会觉得某个人表达沟通很不错,其实不是沟通的问题,是他说出去的话,经过了他大脑的条理清晰的整理,让你很容易就能明白。这种习惯不是一朝一夕就能养成的,所以面试过程中这点装不出来。


另外一个人如果逻辑清晰,而且反应又敏捷,语速很快,那是大大的加分项,恭喜你,碰到一个聪明人了。


具体问哪些问题?


前面提到的是要重点考察的点,那么具体的Android开发,有没有一些通用的问题可以问的呢?我个人一般会从这几个角度考察候选人:


1. Android经验


如果不是校招,Android经验是必须的,我比较喜欢问一些基础概念与技术原理,比如Activity、View、Window的理解,各 LaunchMode的使用场景,View的绘制流程,Touch事件机制,Android动画的原理,Handler,Looper的理解,Android跨进程通讯的方式,Binder的理解,Android Mashup设计的理解等等。


2. Java水平


基本上就是Effective Java那本书里提到的东西,如果你背完那本书里的问题,并且对答如流,没问题,就要你这样的。其实也会考察关于final用法,反射原理,注解原理,java编译过程,GC等一些常见问题。


3. IT基础知识


其实就是计算机科班学生学校里学到的一些东西,在校招时这块是重点,社招会放宽,但一些基本的常识是要有的,比如不少人都不知道http的get post有啥区别,https的那个s是什么意思,讲不清进程与线程的概念,不知道二分算法是个啥东西。这些简单问题的筛选,可以过滤一些所谓野路子的程序员,是不是科班出身不重要,搞这行就得对一些基本常识有概念,不然以后怎么愉快的交流呢?


4. 代码质量的认识


我们需要的是一个对代码味道有感觉的人,关于这点,看下《Clean Code》就够了,面试中这点其实不好考察,可以让他聊一聊对代码质量的认识,虽然不能排除对方夸夸其谈,至少想法不多,只能提到命名风格这一点的人是不符合要求的,也可以在写Code的环节中观察。


5. 技术视野


比如对Android开发新技术的了解与学习,对其它流行技术领域的了解,这其实与我刚才提到的技术广度的考察有关,就我面试过程中,发现很多非互联网行业的从业人员,因为公司各种操蛋规定与公司技术氛围的原因,技术视野相当狭窄。


我个人对这点深有体会,2011年我还在传统行业从事软件研发,当时的公司因为担心技术信息泄露,不让上网,相当封闭,我个人虽然自认为已在那个行业内做到业内专家的级别,但总感觉哪里不对,有一天我很兴奋的打算跟身边同事聊一聊Android的时候,发现他们居然都不知Android为何物?2011年啊同志们,当时的震惊无法言表,深切感觉到需要作出改变了,毅然放弃多年行业积累,转战移动互联网,直到现在。时至今日,多年前的小伙伴也有很多混出了名党,开始走向人生巅峰,我也从来没有后悔当初做出的选择。


6. 技术想象力


一个优秀的技术人,如果知识的深度与广度足够,知识已成体系,那么他对于一些从未接触过的领域,也是可以做出足够合理的想象与判断,面试过程中如果问到一些领域候选人没有涉猎,这时候一般不用过多纠缠,但如果你想借这个问题考察下他的技术想象力,可以深入下去,比如问他:“你觉得这个东西应该是什么原理呢?”,“这个酷炫的控件,如果要你来做,你会怎么实现?”。在这方面表现出色的同学无疑是有深厚基础与足够广度的人。


7. 技术习惯


好的程序员都会有好的习惯,比如各种快捷键的熟练应用,各种命令行的掌握,一些提高开发效率的工具与习惯,碰到问题是baidu还是google,有没有做一些小工具帮助减少重复工作,工作之余有没有继续学习?有没有看什么不错的书等等,这些小细节很大程度上决定了程序员的开发效率,这也是为什么很多人说一个优秀程序员抵得上100个普通程序员,这也是重要原因之一。

面试后的反馈:


面试一般不止一轮,你需要给出你的反馈,多轮面试结果一起考量,减少误判的风险,反馈一般怎么写呢?以下是我的建议:


1. 面试纪录


面试过程中的完整纪录,尽量客观评价,让其它面试官知道你问了哪些问题,回答的怎么样,也避免了重复问题的尴尬。


2. 优点与缺点


你的主观评价,亮点有哪些,你觉得哪些地方不够好?


3. 综合评价


你对候选人的综合评价,hire或者no hire的根本原因,如果有些地方感觉没考察清楚,期望其它面试官继续加强考察,也可以写上。


4. 怎样才给通过?


通过标准因人而异,每个人都有自己心中的bar, 但还是有些可直观考量的因素的:


    一是岗位的要求,不同的岗位标准当然不一样,校招与设招肯定也不一样。


    二是岗位的紧急程度,兄弟们天天加班忙死了,赶紧找人过来帮忙吧哈哈。


    三是候选人的年龄,大龄程序员莫怪,一把年纪了还跟刚毕业一两年的同事一个水平,说明成长太慢,做技术的潜力有限,这个大家应该能理解。


    四是前面提到的做技术的深度,这个是必须的,广度也要有一些,视野不能太窄。


    五是要有亮点,大家在面试的过程中要注意发掘亮点,有时候他问题很多但有一个足够的亮点也够了,用心观察也发现不了什么亮点的,就要注意了。


说了这么水平多,其实最重要的就是一句话,问问你自己:你真的原意跟那个家伙一起并肩战斗吗?

有问题可以加我们技术大牛《qq1225682794》随时帮你解答。

Android翻页特效

Android翻页特效

IT蓝豹|2016/1/4737 阅

对大家有帮助可以看看,

android-flip 是一个能够轻松帮你实现水平以及竖直翻页特效的库,但是在判断翻页的时候有bug,我们需要在FlipCards.java中找到这一段:

 

1
2
3
if (Math.abs(getPageIndexFromAngle(accumulatedAngle + angleDelta) - lastPageIndex) <= 1) {
              accumulatedAngle += angleDelta;
           }

将它更改为:

1
2
3
4
5
6
if(((accumulatedAngle + angleDelta > lastPageIndex*180)
                && (accumulatedAngle + angleDelta <= (lastPageIndex+1) * 180)) || 
                ((accumulatedAngle + angleDelta < lastPageIndex*180) &&
                    (accumulatedAngle + angleDelta >= (lastPageIndex-1) * 180))){
              accumulatedAngle += angleDelta;
            }


而在翻页的时候会有闪烁现象产生,为了减轻现象的发生,我们需要修改另外一个地方,在FlipViewController.java中找到这一段:

1
2
3
4
5
6
7
8
9
10
void postHideFlipAnimation() {
      if (inFlipAnimation) {
        handler.post(new Runnable() {
          @Override
          public void run() {
            hideFlipAnimation();
          }
        });
      }
    }


修改为:

1
2
3
4
5
6
7
8
9
10
void postHideFlipAnimation() {
      if (inFlipAnimation) {
        handler.postDelayed(new Runnable() {
          @Override
          public void run() {
            hideFlipAnimation();
          }
        }, 200);
      }
    }


然后我们就可以轻松地用它来为我们的app添加翻页特效,在Activity中添加代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.nekocode.xuedao;
 
import android.os.Bundle;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.aphidmobile.flip.FlipViewController;
import com.nekocode.xuedao.adapter.SubscribeIndexAdapter;
 
public class SubsecribeIndexActivity extends SherlockFragmentActivity {
    private PublicData pd;
    private FlipViewController mFlipView;
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pd = PublicData.getInstance();
         
        mFlipView = new FlipViewController(this, FlipViewController.HORIZONTAL);
        mFlipView.setAdapter(new SubscribeIndexAdapter(this));
         
        setContentView(mFlipView);
    }
 
    @Override
    protected void onResume() {
        super.onResume();
        mFlipView.onResume();
    }
 
    @Override
    protected void onPause() {
        super.onPause();
        mFlipView.onPause();
    }
}


创建FlipAdapter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.nekocode.xuedao.adapter;
 
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
 
import com.aphidmobile.utils.UI;
import com.nekocode.xuedao.R;
 
public class SubscribeIndexAdapter extends BaseAdapter {
  private LayoutInflater inflater;
 
  public SubscribeIndexAdapter(Context context) {
    inflater = LayoutInflater.from(context);
  }
 
  @Override
  public int getCount() {
    return 5;
  }
 
  @Override
  public Object getItem(int position) {
    return position;
  }
 
  @Override
  public long getItemId(int position) {
    return position;
  }
 
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View layout = convertView;
    if (convertView == null) {
      layout = inflater.inflate(R.layout.item_subscribe_index, null);
    }
 
    UI
        .<TextView>findViewById(layout, R.id.textView7)
        .setText("今日热点" + position);
 
    return layout;
  }
}

 

android ListView之BaseAdapter的使用方法

android ListView之BaseAdapter的使用方法

IT蓝豹|2016/1/4688 阅

通常在使用自定义适配器的时候,我们都会掌握一种固定的模式。充分利用convertView+缓存的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    private ArrayList<listbean> list ;
    private LayoutInflater mInflater;
    public DetailListAdapter(Context context,ArrayList<listbean> list){
        this.list=list;
        mInflater = LayoutInflater.from(context);
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return list == null ?0:list.size();
    }
 
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }
 
    @Override
    public long getItemId(int position) {
        return position;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(convertView == null){
            convertView = mInflater.inflate(R.layout.search_info_item_layout, null);
            holder = new ViewHolder();
            holder.TimeTxt = (TextView) convertView.findViewById(R.id.time_tv);
            holder.AddressTxt = (TextView) convertView.findViewById(R.id._address_tv);
            holder.processFlagTxt = (TextView) convertView.findViewById(R.id.process_flag_tv);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.TimeTxt.setText(list.get(position).getTime());
        holder.AddressTxt.setText(list.get(position).getAddress());
        holder.processFlagTxt.setText(list.get(position).getState());
        return convertView;
    }
    class ViewHolder{
        TextView TimeTxt;
        TextView AddressTxt;
        TextView processFlagTxt;
    }
}</listbean></listbean>

 最近,做百度地图离线下载的时候,发现一种新的方式,很想知道百度的android程序员是如何来写代码的。仔细一看,确实有很大不同。

来自百度地图离线下载的Demo。

private ArrayList<mkolupdateelement> localMapList = null;
    public class LocalMapAdapter extends BaseAdapter {
 
        @Override
        public int getCount() {
            return localMapList.size();
        }
 
        @Override
        public Object getItem(int index) {
            return localMapList.get(index);
        }
 
        @Override
        public long getItemId(int index) {
            return index;
        }
 
        @Override
        public View getView(int index, View view, ViewGroup arg2) {
            MKOLUpdateElement e = (MKOLUpdateElement) getItem(index);
            view = View.inflate(OfflineDemo.this,
                    R.layout.offline_localmap_list, null);
            initViewItem(view, e);
            return view;
        }
 
        void initViewItem(View view, final MKOLUpdateElement e) {
            Button display = (Button) view.findViewById(R.id.display);
            Button remove = (Button) view.findViewById(R.id.remove);
            TextView title = (TextView) view.findViewById(R.id.title);
            TextView update = (TextView) view.findViewById(R.id.update);
            TextView ratio = (TextView) view.findViewById(R.id.ratio);
            ratio.setText(e.ratio + "%");
            title.setText(e.cityName);
            if (e.update) {
                update.setText("可更新");
            } else {
                update.setText("最新");
            }
            if (e.ratio != 100) {
                display.setEnabled(false);
            } else {
                display.setEnabled(true);
            }
            remove.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    mOffline.remove(e.cityID);
                    updateView();
                }
            });
            display.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.putExtra("x", e.geoPt.longitude);
                    intent.putExtra("y", e.geoPt.latitude);
                    intent.setClass(OfflineDemo.this, BaseMapDemo.class);
                    startActivity(intent);
                }
            });
        }
 
    }
</mkolupdateelement>
 
 
Android特效开发

Android特效开发

IT蓝豹|2015/12/291184 阅

本次我要向大家介绍一个Android特效,这个特效也是我在某款软件中看到的,至于软件叫什么,
好了,我来上一张动态效果图 在下面,屏幕小的请往下拉。

我不知道原软件是怎么个实现法,在这里我只是说说我的实现方法,代码可能不太好,这只是本人的一个idea 原理很简单!


改变按钮的宽度,每次当你点击按钮时,只有两个按钮改变宽度,一个变长,一个变短,只是这个变化是慢慢

进行,不是秒变的,你懂的,这就是动画效果。你点击短的按钮后会渐渐地变长,长的按钮会随着被压缩,其他按钮宽度不变。

 我写这篇文章想起到一个抛砖引玉的效果,希望读者看了这篇文章后继续写个更好的文章。当然你不要忘记我啊,

记得要与我和大家分享啊。

 下面是特效Demo运行后的效果图:


可以看到view被挤压的效果,点击短的view会慢慢长大。在短的view慢慢长大的同时,最长的view会慢慢缩小,而且每次动画结束后都

有一个最长的view 。我这里所说的view在本次Demo中是按钮,当然你也可以换成其他的控件,或者是ViewGroup的子类也行。
[java] view plaincopyprint?

    public class PinchActivity extends Activity implements View.OnClickListener {  
      
        private final static String TAG = "MainActivity";  
          
        // 屏幕宽度  
        private int screentWidth = 0;  
          
        // View可伸展最长的宽度  
        private int maxWidth;  
          
        // View可伸展最小宽度  
        private int minWidth;  
          
        // 当前点击的View  
        private View currentView;  
          
        // 显示最长的那个View  
        private View preView;  
          
        // 主布局ViewGroup  
        private LinearLayout mainContain;  
          
        // 标识符 动画是否结束  
        private boolean animationIsEnd = true;  
          
        // 变大操作  
        private static final int OPE_BIG = 1;  
          
        // 变小操作  
        private static final int OPE_SMALL = 2;  
          
        // 当前操作 -1表示无效操作  
        private int currentOpe = -1;  
          
        // 前进的步伐距离  
        private static final int STEP = 10;  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState)   
        {  
      
            super.onCreate(savedInstanceState);  
              
            setContentView(R.layout.activity_main);  
      
            initCommonData();  
              
            initViewData();  
              
            measureWidth(screentWidth);   
      
        }  
      
        private void initViewData() {  
      
            mainContain = (LinearLayout) this.findViewById(R.id.main_contain);  
            View child;  
            int childCount = mainContain.getChildCount();  
            for (int i = 0; i < childCount; i++) {  
                child = mainContain.getChildAt(i);  
                child.setOnClickListener(this);  
            }  
        }  
          
        private void initCommonData()  
        {  
            DisplayMetrics metric = new DisplayMetrics();  
            getWindowManager().getDefaultDisplay().getMetrics(metric);  
            screentWidth = metric.widthPixels; // 屏幕宽度(像素)  
        }  
      
      
        private void setCurrentViewParams() {  
      
            if (currentView == null) {  
                return;  
            }  
            LayoutParams params = currentView.getLayoutParams();  
            if (params == null) {  
                return;  
            }  
            int realWidth = params.width;  
            int nextWidth = 0;  
            if (currentOpe == OPE_BIG) {  
                nextWidth = realWidth + STEP;  
            } else if (currentOpe == OPE_SMALL) {  
                nextWidth = realWidth - STEP;  
            }  
            if (nextWidth > maxWidth) {  
                nextWidth = maxWidth;  
            } else if (nextWidth < minWidth) {  
                nextWidth = minWidth;  
            }  
            params.width = nextWidth;  
            currentView.setLayoutParams(params);  
            if (nextWidth == maxWidth || nextWidth == minWidth) {  
                animationIsEnd = true;  
                onOffClickable();  
                stopAnimation();  
                return;  
            }  
            mHandler.sendEmptyMessageDelayed(1, 20);  
        }  
      
        // 初始化宽度 测量max min 长度  
        private void measureWidth(int screenWidth) {  
              
            int halfWidth = screenWidth / 2;  
            maxWidth = halfWidth - 50;  
            minWidth = (screenWidth - maxWidth) / (mainContain.getChildCount() - 1);  
      
            View child;  
            int childCount = mainContain.getChildCount();  
            for (int i = 0; i < childCount; i++) {  
                child = mainContain.getChildAt(i);  
                LayoutParams params = child.getLayoutParams();  
                if (i == 0) {  
                    preView = child;  
                    params.width = maxWidth;  
                } else {  
                    params.width = minWidth;  
                }  
      
                child.setLayoutParams(params);  
            }  
        }  
      
        // 这里用handler更新界面  
        private Handler mHandler = new Handler() {  
      
            @Override  
            public void handleMessage(Message msg) {  
      
                if (msg.what == 1) {  
                    setCurrentViewParams();  
                }   
            }  
      
        };  
      
        // 停止动画  
        private void stopAnimation() {  
            currentOpe = -1;  
            currentView = null;  
        }  
      
        private void startAnimation() {  
      
            if (currentView == null || currentOpe == -1) {  
                Log.d(TAG, "无效动画");  
                return;  
            }  
              
            animationIsEnd = false;  
            onOffClickable();  
            mHandler.sendEmptyMessage(1);  
        }  
      
        @Override  
        public void onClick(View v) {  
              
            int id = v.getId();  
              
            switch (id) {  
              
            case R.id.btnOne:  
                currentView = mainContain.getChildAt(0);  
                break;  
            case R.id.btnTwo:  
                currentView = mainContain.getChildAt(1);  
                break;  
            case R.id.btnThree:  
                currentView = mainContain.getChildAt(2);  
                break;  
            case R.id.btnFour:  
                currentView = mainContain.getChildAt(3);  
                break;  
            }  
      
            Log.i(TAG, ((Button) currentView).getText().toString() + " click");  
              
            if (currentView != null && animationIsEnd) {  
                  
                int currentViewWidth = currentView.getWidth();  
                  
                if (currentViewWidth == maxWidth) {  
                    currentOpe = OPE_SMALL;  
                } else {  
                    currentOpe = OPE_BIG;  
                }  
                  
                clickEvent(currentView);  
                  
                startAnimation();  
            }  
      
        }  
      
        private void clickEvent(View view) {  
            View child;  
            int childCount = mainContain.getChildCount();  
            for (int i = 0; i < childCount; i++) {  
                child = mainContain.getChildAt(i);  
                if (preView == child) {  
                    LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child  
                            .getLayoutParams();  
                    params.weight = 1.0f;  
                    child.setLayoutParams(params);  
                } else {  
                    LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child  
                            .getLayoutParams();  
                    params.weight = 0.0f;  
                    params.width = minWidth;  
                    child.setLayoutParams(params);  
                }  
            }  
            preView = view;  
            printWeight();  
        }  
      
        private void printWeight() {  
            View child;  
            int childCount = mainContain.getChildCount();  
            for (int i = 0; i < childCount; i++) {  
                child = mainContain.getChildAt(i);  
                LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child  
                        .getLayoutParams();  
                Log.i("mm1", ((Button) child).getText() + ": " + params.weight);  
            }  
        }  
          
        //   
        private void onOffClickable()  
        {  
            View child;  
            boolean clickable = animationIsEnd;  
            int childCount = mainContain.getChildCount();  
            for (int i = 0; i < childCount; i++) {  
                child = mainContain.getChildAt(i);  
                child.setClickable(clickable);  
            }  
        }  
      
    }
大家学了过后,有没有帮助啊。学android特效上IT蓝豹。

 

 android ListView 九大重要属性详细分析

android ListView 九大重要属性详细分析

IT蓝豹|2015/12/15964 阅

1.android ListView 一些重要属性详解,兄弟朋友可以参考一下。
首先是stackFromBottom属性,这只该属性之后你做好的列表就会显示你列表的最下面,值为true和false。

android:stackFromBottom="true"。

2.transciptMode属性,需要用ListView或者其它显示大量Items的控件实时跟踪或者查看信息,并且希望最新的条目可以自动滚动到可视范围内。通过设置的控件transcriptMode属性可以将Android平台的控件(支持ScrollBar)自动滑动到最底部。
android:transcriptMode="alwaysScroll"

3.cacheColorHint属性,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然后指定属性android:background="@drawable/bg",不过不要高兴地太早,当你这么做以后,发现背景是变了,但是当你拖动,或者点击list空白位置的时候发现ListItem都变成黑色的了,破坏了整体效果。

如果你只是换背景的颜色的话,可以直接指定android:cacheColorHint为你所要的颜色,如果你是用图片做背景的话,那也只要将android:cacheColorHint指定为透明(#00000000)就可以了。

4.divider属性,该属性作用是每一项之间需要设置一个图片做为间隔,或是去掉item之间的分割线。

android:divider="@drawable/list_driver"  其中  @drawable/list_driver 是一个图片资源,如果不想显示分割线则只要设置为android:divider="@drawable/@null" 就可以了。

5.fadingEdge属性,上边和下边有黑色的阴影。

android:fadingEdge="none"设置后没有阴影了~

6.scrollbars属性,作用是隐藏listView的滚动条,

android:scrollbars="none"与setVerticalScrollBarEnabled(true);的效果是一样的,不活动的时候隐藏,活动的时候也隐藏。

7.fadeScrollbars属性,android:fadeScrollbars="true"  配置ListView布局的时候,设置这个属性为true就可以实现滚动条的自动隐藏和显示。

8.fastScrollEnabled属性 ,

很多开发者不知道ListView列表控件的快速滚动滑块是如何启用的,这里Android开发网告诉大家,辅助滚动滑块只需要一行代码就可以搞定,如果你使用XML布局只需要在ListView节点中加入  android:fastScrollEnabled="true" 这个属性即可,而对于Java代码可以通过myListView.setFastScrollEnabled(true); 来控制启用,参数false为隐藏。 还有一点就是当你的滚动内容较小,不到当前ListView的3个屏幕高度时则不会出现这个快速滚动滑块,同时该方法仍然是AbsListView的基础方法,可以在ListView或GridView等子类中使用快速滚动辅助。

9.drawSelectorOnTop属性。

When set to true, the selector will be drawn over the selecteditem. Otherwise the selector is drawn behind the selected item. Thedefault value is false。

android:drawSelectorOnTop="true" 点击某一条记录,颜色会显示在最上面,记录上的文字被遮住,所以点击文字不放,文字就看不到。

android:drawSelectorOnTop="false"点击某条记录不放,颜色会在记录的后面,成为背景色,但是记录内容的文字是可见的。

 

如何正确改善listview性能

如何正确改善listview性能

IT蓝豹|2015/12/15890 阅

ListView几乎在每个应用中都会用到。用ListView易于展现一些如联系人、菜单等tems信息。这好像可以理所当然地认为Android应该有现成封装好的方式来展现这类数据,最新的实现版就是RecyclerView。它被构建用于高效重复利用views,而不是每次当某个View item进入屏幕时重新创建它。在RecyclerView之前,我们一般使用ListView,而且在今天ListView仍然被广泛使用。虽然ListView也回收views,但它却维持一个空间作为Android中一个最misconfigured的views。我们知道,这个话题在之前已经讨论了很多,但是我今天在这篇博客提及它,是因为在今天我们仍然有很多人在使用ListView时姿势不正确。

下面是LisView的一个所谓标准写法的ArrayAdapter实现代码段。

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
 
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.view_test_row, parent, false);
 
        TextView testName = (TextView)rowView.findViewById(R.id.text_view_test_name);
        TextView testDesc = (TextView)rowView.findViewById(R.id.text_view_test_desc);
 
        //modify TextViews, in some arbitrary way
 
        return rowView;
    }

像这样写一个AdapterView,当你的list一次性显示在屏幕上时这种写法并没有什么问题,但是当拥有大量的items而且每个item的view都非常复杂的时候。这将引发性能问题,上面代码片段里面的方法非常耗性能。当用户滑动屏幕的时候,对于每个子view都要通过LayoutInflater类加装一遍,并且每次都会调用findViewById()来寻找组件。每次findViewById()被调用的时候,View各层次都会遍历一次直到找到对应的ID,对于每个子View都必须这样去找!如果用户滑动手速比较快的话,就可能出现明显的卡顿现象。

为了解决这个问题,我们可以用一个static的类来关联我们之前未曾用到的convertView。

static class ViewHolder(){
 
        TextView testName;
        TextView testDesc;
        
}
 
    @Override
     public View getView(int position, View convertView, ViewGroup parent) {
 
        View rowView = convertView;  //reference to one of the previous Views in the list that we can reuse.
 
        if(convertView == null) {
 
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflater.inflate(R.layout.view_test_row, parent, false);
 
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.testName = (TextView) rowView.findViewById(R.id.text_view_test_name);
            viewHolder.testDesc = (TextView) rowView.findViewById(R.id.text_view_test_desc);
 
            rowView.setTag(viewHolder);
        }
 
        ViewHolder holder = (ViewHolder) rowView.getTag();
        
        //in real code these strings should be in res
        holder.testName.setText("Test"+position);
        holder.testDesc.setText("This is number "+position);
 
        return rowView;
    }

但是,convertView又是什么东东呢?它可以运行ListView跳过某行(row)为了显示内容而需要的一些设置,它是某个当前正退出屏幕的子view。我们可以复用这个子view来显示新的行(row)。当最初显示ListView的时候,一切都是正常初始化的。由于没有任何views可被复用,所以convertView是null。此时,view会被重新加载,但是TextViews组件被找到之后会被保存到一个ViewHolder对象中。我们可以通过调用setTag()和getTag()方法来将数据保存到view中,之后如果需要可以从中取出数据。

这个改变看起来也许没什么大的区别,但是当我们的views更复杂、数量更多的时候,其效率差别就会非常明显了。

我们开发者们,最想做的一件是可能就是做出一个拥有非常棒的用户体验感的项目。

 

Animation 加载动画的创建android特效

Animation 加载动画的创建android特效

IT蓝豹|2015/12/14473 阅

创建 anim目录 loading_animation.xml

android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="+360"
android:duration="1500"
android:startOffset="-1"
android:repeatMode="restart"
android:repeatCount="-1"/>

activity调用

private Animation animation;

private ImageView pb;

// 开始加载数据时调用

animation = AnimationUtils.loadAnimation(WebViewActivity.this,
R.anim.cirle);

pb.startAnimation(animation);// 启动

// 数据加载完后调用

pb.clearAnimation();// 清除

pb.setVisibility(View.GONE);// 隐藏

学Android开发,入门语言java知识点

学Android开发,入门语言java知识点

IT蓝豹|2015/12/7709 阅


Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学java语言吧。 Android开发入门教程 -Java语言,最差也要类似Java的其他面对像对象语言的基础。Java语言方面需掌握如下内容就可以开始学习:

(一)基础语法:

  讲解Java发展史,Java环境搭建,环境变量配置,Java程序的基本结构,java和javac命令的使用,Notepad++工具的使用,语法格式,变量和常量,二进制转换,运算符、表达式,分支结构和循环结构语句,数组与多维数组,冒泡排序,二分查找,随机生成一组不重复的数算法,通过模拟一个双色球案例,把基础语法容融会贯通,打下扎实的基础。

(二)面向对象:

  讲解Java中的OOP/OOD/OOA的知识,深入讲解OOP的封装、继承、多态、抽象的概念与实际应用,涉及内容为类与对象的定义和关系,封装分别在Java EE开发和Android开发中的不同,对象的引用传递,对象的内存分配和GC,构造方法和匿名对象,如何开发和定义一个类,深入讲解String类的原代码原理内部实现、特性和内存管理,通过四种字符串连接时的场景分析来深入理解Java编译期和运行期的区别,String的相关操作方法;static关键字,构造方法私有化,对象数组与动态数组的实现原理,链表数据结构,内部类及优缺点,在EE开发和Android开发的区别和经验;继承的思想,方法重写与重载,super关键字,抽象类、接口和多态的思想,以及真实环境中的应用,Object类,包装类与特性,包与修饰符;课程贯彻的设计模式有:单例模式、工厂模式、策略模式、适配器模式、模板方法模式、代理模式。以及OO设计中的六大原则。通过本节课程你可以彻底理解什么是面向对象编程,加以时日练习,必成大器。

(三)Eclipse与异常处理

  异常的基本处理格式和5大关键字的联合使用,Java中异常处理的新特性,自定义异常类,编译时异常与运行时异常的区别,JVM对异常的处理过程,经过前两节课程共两周多的Notepad++写代码,已经达到了纯手写代码的目的,本节课程开始引入了99.9%的程序员都在使用的集成开发环境Eclipse,他对异常调试的强大支持,会让你叹为观止,当然Eclipse不仅仅只有这些,在这里,你将一一学到。

(四)常用类库API与算法

  讲解StringBuffer类的内部原理,分析原代码实现,与String的区别与应用经验,如何实现国际化程序,日期操作API,Comparable的两种实现,对象克隆,Arrays工具类、Math工具类、Random类的使用,选择排序算法和二叉树数据结构实现,通过本节课程,你将学到常用类库API和工作中最最常见的排序算法和二叉树,本节过后,你的功力又增强了。

(五)IO与New IO

  讲解IO的进和出的问题,汲及File类递归算法与优缺点分析、字节流中的FileInputStream/FileOutputStream,BufferedInputStream/BufferedOutputStream,字符流中的Writer/Reader,PrintStream/PrintWriter,BufferedWriter/BufferedReader,InputStreamWriter/InputStreamReader,还有ArrayInputStream/ArrayOutputStream,DataInputStream/DataOutputStream,对象序列化的原理Serializable,ObjectInputStream/ObjectOutputStream,常用字符编码,新IO的实现原理和区别,性能分析,通过以上对IO体系的掌握,理解一进一出就不再是难事了,最后我们通过装饰者设计模式再深入理解IO宠大实现体系中的整体结构。

(六)集合

  讲解集合框架体系中的相关类使用,涵盖Collection接口分支的List和Set接口,以及他们的实现类:ArrayList、LinkedList、Vector、TreeSet、HashSet、LinkedHashSet,同时扩展Queue、Stack,Map接口分支以及他们的实现类:HashMap、TreeMap、Hashtable,还有JDK1.5的泛型特性,通过分析这些具体类的实现源码,理解线性数据结构,链表数据结构,红黑树数据结构,哈希表数据结构,栈数据结构,队列数据结构,本节课程会让你掌握计算机数据存储的核心算法,如同了解了妹子的内心深处,拿下,那是必然。

(七)多线程与并发

  讲解多线程开发中的相关知识,进程和线程的区别,理解Java线程的两种实现方法及区别,线程的基本控制方法,线程的休眠及原理,多线程之间如何共享数据,以及带来的数据安全问题,如何解决安全问题,同步的原理,同步的两种方式,同步带来的死锁问题如何避免,线程的生命周期,sleep和wait的区别及应用场景,通过经典的生产者消费者案例,让你深入理解多线程并发机制,如何处理并发有并发包的使用,如果你了解JavaEE开发,多线程基本使用不到,因为都让框架封装了,但在Android开发中,多线程应用非常广泛,本课程将为你讲解Android领域如何应用多线程,让你学会知识点的同时知道其应用场景。

(八)网络编程

  讲解网络编程的相关知识,从底层的通信协议TCP、UDP入手,理解什么是三方握手原理,什么是数据包,Socket的原理及作用,使用URL和URLConnection实现网络下载,Socket编程如何实现网络通信,客户端与服务器端的通信,客户端与客户端之间的通信,多客户端之间的通信,在此,结合IO、和多线程个知识点实现自定义通信机制,通过本节课程,你将收获软件之间是如何通信的。


(九)反射与内省

  讲解了什么是反射,反射在应用中的作用,相关反射的API,如Class类,如何通过反射实例化对象,通过对象获取类信息,Field类、Method类、Package类、Constructor类,以及如何修改属性和方法的访问修饰符,本节内容让你理解,在反射面前,一切封装都将成为浮云。同时还讲解了JDK提供的强大内省机制,通过内省,我们可以非常方便的得到类信息,再用反射实现调用。结合JavaEE和Android开发的应用场景,让你理解反射与内省的用武之地,详细观看Android在线课程

(十)泛型、正则、枚举与注解、XML

  讲解了JDK1.5的新特性泛型、注解和枚举,正则表达式,XML文件的SAX、DOM、JDOM和DOM4J四种解析方式。

十一)MySQL数据库

  讲解了数据库产品介绍,MySQL数据库的安装,基本的SQL语句,事务处理,关联查询,内置函数,索引,自定义函数,存储过程,数据库设计与优化,数据库设计,三大范式,通过本节课程的你将掌握数据库的常用操作,和如何设计数据库。

(十二)JDBC

  讲解了如何使用JDBC接口访问数据库,数据库与应用程之间的关系,DriverManager、Connection、Statement、ResultSet、PreparedStatement、CallableStatement,事务处理的概念及应用,DAO设计模式,使用设计模式优化代码结构,dbutil开源框架的使用,通过本节内容,你将掌握使用JDBC访问数据库的方法,用程序操作数据库,不再是难事。

(十三)Servlet

  讲解了HTTP协议,HTML标签的使用,Tomcat服务器,Servlet的原理,JSP基本应用,两种请求方式,最后运用MySQL、JDBC、和Servlet技术实现一个商品管理综合案例,了解企业级BS架构的整体开发流程,为后续的Android应用与服务器之间的交互打下坚实的基础。

 

IT蓝豹为大家整理:www.itlanbao.com

Android开发学习路线图扎实学好每一步-IT蓝豹为你规划。

Android开发学习路线图扎实学好每一步-IT蓝豹为你规划。

IT蓝豹|2015/12/4772 阅

Android开发学习路线图扎实学好每一步-IT蓝豹为你规划。

一些没有接触过Android知识又想学习Android开发的人,看到一行行密密麻麻的代码会感觉到压力,失去学习的信心。其实Android开发并没有想象中那么可怕,通过Android学习的路线图可以让我们明确的规划每一阶段的学习内容。

开始阶段,Java是学习Android的基础,对没有接触过的学员来说,Java编程语言强化的学习很辛苦,但也很重要,Java学习打下扎实的编程基础,让之后的Android学习更加得心应手,学好Java的最好方法就是多练习,另外,设计模式也要把握牢固,后面的Android系统框架层会大量运用设计模式。

接下来就是Android应用开发,有了之前的基础,相对而言,接下来的学习会轻松一些,但作为学习Android开发的核心,Android应用开发在整个学习过程中占据着重要位置,其中UI界面、多媒体、网络、传感器、多点触摸、NFC等学习程度决定了未来的开发方向。在这一阶段,对未来的方向起着决定作用,想要学好Android应用开发,勤练思考必不可少。

当Android应用开发学习到一定程度后,就有能力接触Android游戏开发,对很多学习Android开发的学员来说,游戏开发是大家都向往的,首先熟练游戏引擎基础框架到音效部分和引擎例子系统部分,期间多思考多练习,能熟练地把游戏引擎音效部分实现和游戏引擎粒子系统部分实现,就能使用游戏引擎编写游戏。

Android开发学习主要阶段就是上面所述内容,其中,各个阶段都有相对应的知识点需要学习,以IT蓝豹Android培训机构为例,作为行业最具权威的Android研发和人才培训基地,在游戏开发阶段之后还有Android项目实战,通过企业级的开发流程让学员把知识融合应用到实际项目开发中,前几个阶段能够扎实学好,项目实战其实不难。

Android开发本身就是多练习的过程,多敲代码是学好Android开发的唯一捷径,IT蓝豹教育Android培训四个月,让你在学习Android开发的道路上,一步一个脚印,扎扎实实的走好Android的每一阶段。就算Java基础学习辛苦一段时间,通过四个月的努力换来一身Android开发高技能,这是明智的选择。

每学习一样东西只要是有耐心就会成功,《IT蓝豹