@hx
2018-04-27T23:34:59.000000Z
字数 16873
阅读 1156
Android
Android应用界面开发
自定义控件与Handler
布局列表与列表控件
服务、广播与酷特性Widget
SharedPreferences与文件管理
SQLite和ContentProvider
网络编程和数据处理
多线程
进程与服务
传感器与LBS
Gradle、依赖
1.布局文件中,spinnerMode
:dropdown | dialog
。
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:spinnerMode="dialog"
android:layout_height="wrap_content"/>
2.Java代码
public class MainActivity extends AppCompatActivity {
private ArrayAdapter<String> mArrayAdapter;
private ArrayList<String> mArrayList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = (Spinner) findViewById(R.id.spinner);
// SpinnerMode 为 Dropdown时可设置下拉背景。
spinner.setPopupBackgroundResource(R.drawable.tp);
// Mode为dialog时的提示消息。
spinner.setPrompt("请选择城市");
initDatas();
mArrayAdapter = new ArrayAdapter<>(this, R.layout.support_simple_spinner_dropdown_item, mArrayList);
spinner.setAdapter(mArrayAdapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(), "您选择的城市:" + mArrayList.get(i), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
private void initDatas() {
mArrayList = new ArrayList<>();
mArrayList.add("北京");
mArrayList.add("上海");
mArrayList.add("武汉");
mArrayList.add("长春");
}
}
<ProgressBar
style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:max="100" //进度条最大值
android:progress="50" // 进度条初始值(0-100)
android:secondaryProgress="70" // 第二进度条
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Style样式
Widget.ProgressBar.Horizontal //水平进度条样式
Widget.ProgressBar.Small //小进度条
Widget.ProgressBar.Large //大进度条
Widget.ProgressBar.Inverse //不断跳变并旋转的进度条
Widget.ProgressBar.Small.Inverse //小的不断跳变并旋转的进度条
Widget.ProgressBar.Large.Inverse //大的不变跳变并旋转的进度条
常用方法
方法 | 说明 |
---|---|
incrementProgressBy(int value) | 在原来的基础上每次增加value |
setProgress | 设置进度 |
setMax | 设置进度条最大值 |
getProgress | 获取当前进度 |
setSeconderyProgress | 设置第二进度条进度 |
SeekBar
继承自ProgressBar
,属性基本相同,thumb
属性可设置资源改变滑块样式。
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
textView.setText("开始滑动" + i);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
API中对此类描述:
ViewPager类直接继承自ViewGroup类,作为一个容器类,可以向其中添加View类;
数据源和显示之间需要一个适配器类PagerAdapter进行适配;
ViewPager经常和Fragemnet一起使用,并且提供专门的适配器类FragmentPagerAdapter和FragmentStatePagerAdapter类供开发者调用。
是一个非交互的当前页面指示器,一般指示ViewPager
中的前一页、当前页和下一页三个页面。可以通过PagerTitleStrip
标签添加到xml布局当中。我们可以设置layout_gravity属性为TOP
或者BOTTOM
来决定在页面顶部或者底部显示,添加PagerTitleStri
p要在适配器中覆写getPageTitle
方法。
1.布局文件
android:layout_gravity=""
属性默认为Top
。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.hx.newproject.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTitleStrip
android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
</android.support.v4.view.PagerTitleStrip>
</android.support.v4.view.ViewPager>
</LinearLayout>
2.子文件布局(3个,随意三个布局)
参见 上文“BaseAdapter适配器”的子文件布局。
3.自定义Adapter
public class MyViewPagerAdapter extends PagerAdapter {
private List<View> mList;
private List<String> mTitles;
MyViewPagerAdapter(List<View> list, List<String> titles) {
this.mList = list;
this.mTitles = titles;
}
// 返回页卡数量
@Override
public int getCount() {
return mList.size();
}
// 判断View是否来自Object
@Override
public boolean isViewFromObject(View view, Object o) {
return view == o;
}
// 初始化一个页卡
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mList.get(position));
return mList.get(position);
}
// 销毁一个页卡
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mList.get(position));
}
// 返回指示器title name
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
只需将PaperTitleStrip布局文件中的android.support.v4.view.PagerTitleStrip
替换成android.support.v4.view.PagerTabStrip
即可。
添加addOnPageChangeListener
方法设置换页监听。
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
// 当前页为 i。
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
除了直接添加布局文件外,还可以添加Fragment控件
FragmentPagerAdapter
和FragmentStatePagerAdapter
。
效果图
FragmentPagerAdapte
r和FragmentStatePagerAdapter
的区别:
FragmentStatePagerAdapter
更适用于大量页面的情形,因为不被显示的页面会被回收,可以大大降低内存的使用率。在使用FragmentStatePagerAdapter
作为适配器时,其余都不用改动,只要覆写instantiateItem
(初始化子页面)和destroyItem
(销毁子页面)两个方法即可
1.主布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.hx.newproject.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
<include layout="@layout/nav_button"/>
</LinearLayout>
2.@layout/nav_button
底部导航布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/colorPrimary"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/work_list"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/work_list_image_view"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/ic_import_contacts_black_24dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/forum"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/forum_image_view"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/ic_forum_white_24dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/me"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/me_image_view"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/ic_person_white_24dp"/>
</LinearLayout>
</LinearLayout>
3.子布局文件(3个,随意三个布局)
参见 上文“BaseAdapter适配器”的子文件布局。
4.Fragment文件
public class MyFragment1 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.item, null);
}
}
这些Fragment数据集只是布局文件不同,MyFragment2
-MyFragment3
类似。
5.Aapter代码
public class ViewPagerFragmentAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragmentList;
public ViewPagerFragmentAdapter(FragmentManager fm, List<Fragment> list) {
super(fm);
this.mFragmentList = list;
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
6.MainActivity
public class MainActivity extends FragmentActivity implements View.OnClickListener {
private List<Fragment> mFragmentList;
private ViewPager mViewPager;
private LinearLayout mWorkList;
private LinearLayout mForum;
private LinearLayout mMe;
private ImageView mImageViewWorkList;
private ImageView mImageViewForum;
private ImageView mImageViewMe;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDatas(); // 初始化数据
initViews(); // 初始化控件
initEvent(); // 注册单击监听
ViewPagerFragmentAdapter viewPagerFragmentAdapter =
new ViewPagerFragmentAdapter(getSupportFragmentManager(), mFragmentList);
mViewPager.setAdapter(viewPagerFragmentAdapter);
}
private void initDatas() {
mFragmentList = new ArrayList<>();
mFragmentList.add(new MyFragment1());
mFragmentList.add(new MyFragment2());
mFragmentList.add(new MyFragment3());
}
private void initViews() {
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mWorkList = (LinearLayout) findViewById(R.id.work_list);
mForum = (LinearLayout) findViewById(R.id.forum);
mMe = (LinearLayout) findViewById(R.id.me);
mImageViewWorkList = (ImageView) findViewById(R.id.work_list_image_view);
mImageViewForum = (ImageView) findViewById(R.id.forum_image_view);
mImageViewMe = (ImageView) findViewById(R.id.me_image_view);
}
private void initEvent() {
mWorkList.setOnClickListener(this);
mForum.setOnClickListener(this);
mMe.setOnClickListener(this);
// 设置ViewPager滑动监听
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
// 获取当前ViewPager页数
int currentItem = mViewPager.getCurrentItem();
resetImage();
switch (currentItem) {
case 0:
mImageViewWorkList.setImageResource(R.drawable.ic_import_contacts_black_24dp);
break;
case 1:
mImageViewForum.setImageResource(R.drawable.ic_forum_black_24dp);
break;
case 2:
mImageViewMe.setImageResource(R.drawable.ic_person_black_24dp);
break;
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
}
// 重置图片
private void resetImage() {
mImageViewWorkList.setImageResource(R.drawable.ic_import_contacts_white_24dp);
mImageViewForum.setImageResource(R.drawable.ic_forum_white_24dp);
mImageViewMe.setImageResource(R.drawable.ic_person_white_24dp);
}
@Override
public void onClick(View view) {
resetImage();
switch (view.getId()) {
case R.id.work_list:
// 设置当前页
mViewPager.setCurrentItem(0);
mImageViewWorkList.setImageResource(R.drawable.ic_import_contacts_black_24dp);
break;
case R.id.forum:
mViewPager.setCurrentItem(1);
mImageViewForum.setImageResource(R.drawable.ic_forum_black_24dp);
break;
case R.id.me:
mViewPager.setCurrentItem(2);
mImageViewMe.setImageResource(R.drawable.ic_person_black_24dp);
break;
}
}
}
1.主布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="R"/>
<SeekBar
android:id="@+id/seek_bar_R"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="0"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="G"/>
<SeekBar
android:id="@+id/seek_bar_G"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="0"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"/>
<SeekBar
android:id="@+id/seek_bar_B"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="0"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"/>
<SeekBar
android:id="@+id/seek_bar_A"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="255"/>
<ImageView
android:id="@+id/matrix_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_import_contacts_black_24dp"/>
</LinearLayout>
2.MainActivity
public class MatrixActivity extends AppCompatActivity {
private Bitmap mBitmap;
private Bitmap mAfterBitmap;
private Canvas mCanvas;
private Paint mPaint;
private ImageView mImageView;
private SeekBar mSeekBarR;
private SeekBar mSeekBarG;
private SeekBar mSeekBarB;
private SeekBar mSeekBarA;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_matrix);
initViews();
}
private void initViews() {
mImageView = (ImageView) findViewById(R.id.matrix_image_view);
mSeekBarR = (SeekBar) findViewById(R.id.seek_bar_R);
mSeekBarG = (SeekBar) findViewById(R.id.seek_bar_G);
mSeekBarB = (SeekBar) findViewById(R.id.seek_bar_B);
mSeekBarA = (SeekBar) findViewById(R.id.seek_bar_A);
mSeekBarR.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
mSeekBarG.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
mSeekBarB.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
mSeekBarA.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_import_contacts_black_24dp);
// 获取一个与mBitmap大小一致的可编辑空图片。
mAfterBitmap = Bitmap.createBitmap(
mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
// 使用Bitmap对象创建Canvas,然后创建画笔。
mCanvas = new Canvas(mAfterBitmap);
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener
= new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (seekBar.getId() == R.id.seek_bar_A) {
mImageView.getDrawable().setAlpha(mSeekBarA.getProgress());
} else {
float R = mSeekBarR.getProgress();
float G = mSeekBarG.getProgress();
float B = mSeekBarB.getProgress();
// 根据SeekBar定义RGBA的矩阵, 通过修改矩阵第五列颜色的偏移量改变图片的颜色
float[] src = new float[]{
1, 0, 0, 0, R,
0, 1, 0, 0, G,
0, 0, 1, 0, B,
0, 0, 0, 1, 0,
};
// 定义ColorMatrix,并指定RGBA矩阵
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(src);
// 使用ColorMatrix创建一个ColorMatrixColorFilter对象, 作为画笔的滤镜, 设置Paint的颜色
mPaint.setColorFilter(new ColorMatrixColorFilter(src));
// 通过指定了RGBA矩阵的Paint把原图画到空白图片上
mCanvas.drawBitmap(mBitmap, new Matrix(), mPaint);
mImageView.setImageBitmap(mAfterBitmap);
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
};
}
它是一个浮动在当前界面上方并且可以显示在任意位置的View,
PopupWindow
应该有两点和弹出框不同,一是PopupWindow
必须指定宽高属性,而弹出框则不是必须指定;二是PopupWindow
必须指定其布局文件。
主要方法
常用属性 | |
---|---|
android:autoStart |
设置自动加载下一个View |
android:flipInterval |
设置View之间切换的时间间隔 |
android:inAnimation |
设置切换View的进入动画 |
android:outAnimation |
设置切换View的退出动画 |
常用方法 | |
---|---|
isFlipping |
判断View切换是否正在进行 |
setFilpInterval |
设置View之间切换的时间间隔 |
startFlipping |
开始View的切换,而且会循环进行 |
stopFlipping |
停止View的切换 |
setOutAnimation |
设置切换View的退出动画 |
setInAnimation |
设置切换View的进入动画 |
showNext |
显示ViewFlipper里的下一个View |
showPrevious |
显示ViewFlipper里的上一个View |
一、主要布局
<ViewFlipper
android:id="@+id/view_flipper"
android:layout_width="0dp"
android:layout_height="160dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:background="#b9b1b1"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:autoStart="true"
android:flipInterval="3000"
android:inAnimation="@anim/anim_marquee_in"
android:outAnimation="@anim/anim_marquee_out"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteY="8dp">
</ViewFlipper>
这里还涉及到两个动画其实就是一个平移的动画,它们都保存在anim文件夹中
anim_marquee_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1500"
android:fromYDelta="100%p"
android:toYDelta="0"/>
</set>
anim_marquee_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1500"
android:fromYDelta="0"
android:toYDelta="-100%p"/>
</set>
二、自定义样式
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="@+id/imageButton"
android:layout_width="0dp"
android:layout_height="140dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:scaleType="centerCrop"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteY="2dp"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="0dp"
app:layout_constraintLeft_toLeftOf="@+id/imageButton"
app:layout_constraintRight_toRightOf="@+id/imageButton"
app:layout_constraintTop_toBottomOf="@+id/imageButton"/>
</android.support.constraint.ConstraintLayout>