- 浏览: 403881 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
ysn003:
这样用就好啦!!!<Button ...
Android学习 之 ColorStateList按钮文字变色 -
ysn003:
Android学习 之 ColorStateList按钮文字变色 -
vitoliao:
楼主你好,如果你的代码需要实现的是回显功能,需要在MainCl ...
Java学习 之 Socket(实现简易的C/S聊天室) -
xinqiqi123:
在item布局中要是引用到自定的东西,item就会显示不全
Android学习 之 问题&解答 ScrollView中嵌套ListView时显示不全的简便解决方案 -
CTXsamCTX:
很好,学习了。
Android 图形用户界面 之 绘图(一)
截图见附件:
先准备几张图片吧,在附件那里:(注意:倒数第二张图片附件是个9文件,下载完了记得把后缀改成.9.png)
1.新建一个工程,爱叫什么名随便哈,这不是重点。
我的工程中把main.xml改成了tabmain.xml,因为我的Activity叫TabMain。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/container_frame">
<!-- android:scrollbarThumbHorizontal="@drawable/scrollbar" -->
<!-- android:scrollbarAlwaysDrawHorizontalTrack="false" -->
<!-- android:scrollbarStyle="outsideOverlay" -->
<!-- android:fadingEdge="horizontal" -->
<!-- android:fadingEdgeLength="5.0dip" -->
<HorizontalScrollView
android:scrollbars="none"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/horizontal_bg"
android:id="@+id/container_horizontal">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="@dimen/horizontal_height">
</LinearLayout>
</HorizontalScrollView>
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="@dimen/horizontal_height"
android:id="@+id/container_relative">
<ImageButton
android:id="@+id/left_image"
android:layout_alignParentLeft="true"
android:visibility="gone"
android:layout_width="@dimen/imagebutton_width"
android:layout_height="fill_parent"
android:background="@drawable/arrowl" />
<ImageButton
android:id="@+id/right_image"
android:layout_alignParentRight="true"
android:visibility="gone"
android:layout_width="@dimen/imagebutton_width"
android:layout_height="fill_parent"
android:background="@drawable/arrowr" />
</RelativeLayout>
</FrameLayout>
2.修改AndroidManifest.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ql.app"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".TabMain"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden|navigation" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" ></uses-permission>
</manifest>
3.在res/values文件夹下新建一个xml文件,attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="custom">
<attr name="arrayId" format="reference" />
</declare-styleable>
</resources>
同样的,新建一个deimens.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="horizontal_height">50dip</dimen>
<dimen name="textview_width">120dip</dimen>
<dimen name="textview_size_big">25sp</dimen>
<dimen name="textview_size_small">20sp</dimen>
<dimen name="imagebutton_width">25dip</dimen>
</resources>
3.重点来了,这个是TabMain.java
package com.ql.app;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
public class TabMain extends Activity{
/**
* 水平滚动容器,内含一个LinearLayout,所有的子控件都在该LinearLayout容器中
* ,因此,获取子控件的时候应该先通过horizontalScrollView.getChildAt(0)获取
* 到该LinearLayout,然后再通过该LinearLayout的getChildAt()方法获取。
*/
private HorizontalScrollView horizontalScrollView;
/**
* horizontalScrollView的唯一子控件容器
*/
private LinearLayout horizontalLinearLayout;
/**
* 左边的箭头控件
*/
private ImageButton leftImage;
/**
* 右边的箭头控件
*/
private ImageButton rightImage;
/**
* 屏幕的宽度值
*/
private int mScreenW;
/**
* horizontalLinearLayout容纳文本控件的总长度
*/
private int mMeasuredW;
/**
* 文本控件字体大小值:大字体
*/
private int textSizeBig;
/**
* 文本控件字体大小值:小字体
*/
private int textSizeSmall;
/**
* 初始化时将被选中的标题索引值
*/
private int mSelectPosition = 3;
/**
* 标题内容数组
*/
// private String[] titleArrays = {"访客"};
// private String[] titleArrays = {"访客","新鲜事"};
// private String[] titleArrays = {"访客","新鲜事","资料"};
private String[] titleArrays = {"访客","新鲜事","资料","留言板","相册","日记","状态","分享","收藏"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mSelectPosition < 0) {
throw new ArrayIndexOutOfBoundsException("初始化被选中的标题索引值mSelectPosition不能小于0");
} else if (mSelectPosition >= titleArrays.length) {
throw new ArrayIndexOutOfBoundsException("初始化被选中的标题索引值mSelectPosition不能大于或等于标题总个数");
}
setContentView(R.layout.tabmain);
init();
}
/**
* 初始化
*/
private void init(){
Resources res = getResources();
textSizeBig = (int) res.getDimension(R.dimen.textview_size_big);
textSizeSmall = (int) res.getDimension(R.dimen.textview_size_small);
int textWidth = 0;
mScreenW = getResources().getDisplayMetrics().widthPixels;
horizontalScrollView = (HorizontalScrollView) findViewById(R.id.container_horizontal);
horizontalLinearLayout = (LinearLayout) horizontalScrollView.getChildAt(0);
leftImage = (ImageButton) findViewById(R.id.left_image);
rightImage = (ImageButton) findViewById(R.id.right_image);
int titleLength = titleArrays.length;
// 注意,水平滚动容器中的LinearLayout与普通的LinearLayout不一样
// 我们只能手动配置params的宽度值才能有效果,设置成FILL_PARENt或
// 比例params.weight也不起任何作用,效果都是WRAP_CONTENT。
LayoutParams params = null;
// 对标题长度进行判断,手动设置文本控件的宽度值
switch (titleLength) {
case 1:
textWidth = mScreenW;
break;
case 2:
textWidth = mScreenW >> 1;
break;
case 3:
textWidth = mScreenW / 3;
break;
default:// 当标题数组的长度大于3个的时候才它设置监听
textWidth = (int) res.getDimension(R.dimen.textview_width);
horizontalScrollView.setOnTouchListener(onTouchListener);
break;
}
params = new LinearLayout.LayoutParams(textWidth, LayoutParams.FILL_PARENT);
for (int i = 0; i < titleLength; i++) {
TextView textView = new TextView(this);
textView.setText(titleArrays[i]);
textView.setTextColor(Color.parseColor("#aaaaaa"));
if (i == mSelectPosition) {
// 设置被选中的这个文本控件给horizontalLinearLayout
horizontalLinearLayout.setTag(textView);
textView.setTextColor(Color.parseColor("#ffffff"));
textView.setBackgroundResource(R.drawable.tab_select);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeBig);
} else {
textView.setTextColor(Color.parseColor("#aaaaaa"));
textView.setBackgroundDrawable(new BitmapDrawable());
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSmall);
}
textView.setOnClickListener(clickListener);
textView.setGravity(Gravity.CENTER);
horizontalLinearLayout.addView(textView,params);
}
// 当标题数组的长度小于3的时候,每个文本控件都是平铺在屏幕上的
// 只有大于3的时候,进行初始化操作时,才去判断是否要显示箭头
if (titleLength > 3) {
mMeasuredW = titleArrays.length * textWidth;
// 为了判断初始化被选中的文本控件的中心位置是否超过了半个屏幕
int tempInitScrollValue = (int) ((mSelectPosition + 0.5 ) * textWidth) - mScreenW/2;
Log.d("debug", "tempMeasuredW = "+mMeasuredW);
if (mMeasuredW > mScreenW) {
rightImage.setVisibility(View.VISIBLE);
}
if (tempInitScrollValue > 0) {
leftImage.setVisibility(View.VISIBLE);
// 发送消息让horizontalScrollView滚动
Message msg = new Message();
msg.what = 1;
msg.obj = String.valueOf(tempInitScrollValue);
handler.sendMessageDelayed(msg, 200);
}
}
}
private View.OnTouchListener onTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
// 抬起的时候发送消息去判断是否要显示箭头
case MotionEvent.ACTION_UP:
if(v != null){
handler.sendEmptyMessageDelayed(0, 500);
}
break;
}
return false;
}
};
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
Rect localRect = new Rect();
horizontalScrollView.getLocalVisibleRect(localRect);
Log.d("debug", "horizontalScrollView`s Rect2 > l:"+localRect.left+" , r:"+localRect.right+
" W:"+horizontalLinearLayout.getMeasuredWidth());
// 滑动的x值
int tempScrollX = horizontalScrollView.getScrollX();
Log.d("debug", "scrollX = "+tempScrollX);
// 判断是不是达到了最左边或最右边
if (localRect.left == 0 || tempScrollX == 0) {// 最左边
// 隐藏左箭头框
leftImage.setVisibility(View.GONE);
} else {
leftImage.setVisibility(View.VISIBLE);
}
if (localRect.right == mMeasuredW || tempScrollX == mMeasuredW - mScreenW) {// 最右边
// 隐藏右箭头框
rightImage.setVisibility(View.GONE);
} else {
rightImage.setVisibility(View.VISIBLE);
}
break;
case 1:
horizontalScrollView.smoothScrollBy(Integer.parseInt((String)msg.obj), 0);
break;
}
};
};
OnClickListener clickListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 点击的时候,从horizontalLinearLayout中获取未点击前那个
// 被选中的文本控件对象,并变换其颜色,背景,字体大小
TextView beforeView = (TextView) horizontalLinearLayout.getTag();
beforeView.setTextColor(Color.parseColor("#aaaaaa"));
beforeView.setBackgroundDrawable(new BitmapDrawable());
beforeView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSmall);
// 变换被点击文本控件的颜色,背景,字体大小
TextView clickTextView = ((TextView)v);
clickTextView.setTextColor(Color.parseColor("#ffffff"));
clickTextView.setBackgroundResource(R.drawable.tab_select);
clickTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeBig);
// 把当前被点击的文本控件设置给horizontalLinearLayout
horizontalLinearLayout.setTag(clickTextView);
// 当标题控件个数大于3的时候才去判断滚动与否
if (titleArrays.length > 3) {
scroll(v);
}
}
};
private void scroll(View v){
Rect vRect = new Rect();
v.getLocalVisibleRect(vRect);
// Log.d("debug", "Click View`s vRect > l:"+vRect.left+" , t:"+vRect.top+" , r:"+vRect.right+" , b:"+vRect.bottom);
int[] hScreen = new int[2];
v.getLocationOnScreen(hScreen);
// Log.d("debug", "Click View`s hScreen = ("+hScreen[0]+" , "+hScreen[1]+")");
/*int[] hWindow = new int[2];
v.getLocationInWindow(hWindow);
Log.d("debug", "Click View`s hWindow = ("+hWindow[0]+" , "+hWindow[1]+")");
Rect localRect = new Rect();
horizontalScrollView.getLocalVisibleRect(localRect);
Log.d("debug", "horizontalScrollView`s Rect > l:"+localRect.left+" , t:"+localRect.top
+" , r:"+localRect.right+" , b:"+localRect.bottom);*/
int tempScreenW = getResources().getDisplayMetrics().widthPixels;
int viewW = v.getWidth();
// Log.d("debug", "onClick >> tempScreenW = "+tempScreenW+" viewW = "+viewW);
int scrollValue = 0;
if (vRect.left > 0 && vRect.right == viewW) {
scrollValue = -((tempScreenW-viewW)/2+vRect.left);
// Log.d("debug", "左入 >> scrollValue = "+scrollValue);
} else if ((vRect.left == 0 && vRect.right == viewW)
|| (vRect.left == 0 && vRect.right < viewW)) {
scrollValue = hScreen[0] + viewW/2 -tempScreenW/2;
// Log.d("debug", "屏显,右入 >> scrollValue = "+scrollValue);
}
Message msg = new Message();
msg.what = 1;
msg.obj = String.valueOf(scrollValue);
handler.sendMessageDelayed(msg, 300);
handler.sendEmptyMessageDelayed(0, 500);
}
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
Log.d("debug", "onConfigurationChanged");
switch (newConfig.orientation) {
// 纵向
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
Log.d("debug", "------------------ >> 纵向");
break;
// 横向
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
Log.d("debug", "------------------ >> 横向");
break;
}
super.onConfigurationChanged(newConfig);
}
}
5.好了,大功告成。运行看效果吧 o(∩_∩)o
评论
哈哈 不客气
我来评价一下
杯具的小男人!!!
靠,你个贱人,怎么哪都有你的份捏
我来评价一下
杯具的小男人!!!
发表评论
-
Android 学习 之 Android 4.0 平台
2011-10-21 19:04 10877转转转,感谢饿哦额Android的各位大侠,在这里谢过,我这里 ... -
Android 学习 之 Activity 堆栈信息
2011-09-28 10:47 4305在android中,一个activity组件可以激活另一个ac ... -
Android 学习 之 无需类名启动其他程序
2011-08-03 09:23 3701在网上搜索了一会相关的实现代码,发现所有的文章都说是需要包名和 ... -
Android 学习 之 Looper Handler Thread Messahe 多线程
2011-07-04 15:31 2227转载请说明,转载自 ... -
Java学习 之 使用反射来获取泛型信息
2011-05-30 18:34 8014通过指定类对应的Class对象,程序可以获得该类里包括 ... -
【原创】Android学习 之 控件篇 Progressbar-设置自己的样式
2011-05-10 12:03 765----------------------- 广 ...
相关推荐
在Android应用开发中,底部导航条(Bottom Navigation Bar)是一种常见的设计模式,它允许用户在应用的几个主要功能之间快速切换。"底部导航条"通常包含3到5个图标按钮,每个图标代表一个不同的功能区域,点击后会...
底部播放条的歌曲信息可以滑动切换,并且专辑图会转动 ##看看截图: Dependency - 依赖 Java Development Kit (JDK) 7 + com.android.tools.build:gradle:1.0.0 Android SDK Android SDK Build-tools 21.1.2 Build -...
在本文中,我们将深入探讨如何使用Node.js创建一个定制的视图组件,该组件模仿了Material Design中的底部导航模式。Material Design是Google推出的一种设计语言,它为移动和Web应用程序提供了一套统一的设计规范和...
iOS的主菜单通常采用滑动式页面布局,每个页面代表一个应用或功能模块,而Android则是通过抽屉式导航(Navigation Drawer)或者底部导航栏(Bottom Navigation Bar)来展示应用的主要功能。为了在Android上模仿...
3. **数据绑定**:为了使底部导航条与应用的功能部分关联,开发者可能需要实现数据绑定或代理协议。这可能涉及到`MVVM`(Model-View-ViewModel)架构,通过`Observable`对象来同步视图状态。 4. **状态管理**:为了...
在这个项目中,ViewPager被用来模仿微信的底部导航栏,通过滑动或点击在不同的Activity之间进行切换。 2. **PagerAdapter**:PagerAdapter是ViewPager的数据适配器,它继承自PagerAdapter接口,需要重写`...
主页(MainActivity)通常会包含一个底部导航栏,这可以通过使用TabLayout和ViewPager实现。TabLayout可以创建可切换的标签,而ViewPager则用于滑动浏览不同页面。每个标签页可能对应一个不同的Fragment,这是一种轻...
标签“Android开发-导航条”可能意味着这个控件的样式或功能与Android应用中的导航条设计有关,尽管标题提到了Node.js,这可能意味着存在一个跨平台的应用,或者至少是开发者可以借鉴的Android设计原则。Android导航...
本示例中的"仿网易新闻客户端的上面的tab和下面的功能条"就是一个典型的案例,旨在帮助开发者掌握如何在Android上构建类似网易新闻客户端顶部Tab栏和底部功能导航条。 首先,顶部Tab栏是Android应用中常用的一种...
5. **导航栏和底部导航**:iOS的顶部导航栏和底部TabBar在Android中可以使用ToolBar和BottomNavigationView来实现,调整它们的样式和行为,如固定的底部导航栏,以及隐藏/显示的顶部导航栏。 其次,关于UX的模仿: ...
这包括使用CardView展示每条便签,以及底部导航栏或者抽屉式菜单来切换不同的功能模块。 描述中提到了“内有截图”,这意味着应用可能集成了图像处理功能。Android系统提供MediaStore API,可以用来读取、保存和...
在“仿微信”项目中,可能采用了类似微信的底部导航栏,通过切换Fragment来展示不同内容。 3. **聊天界面(Chat Interface)**:聊天界面是微信的核心功能之一,涉及到消息发送、接收、显示以及输入框交互等复杂...
1. **底部导航栏**:这是应用的主要导航元素,通常固定在屏幕底部,包括几个图标按钮,每个代表一个主要功能模块,如“首页”、“购物”、“我的”等。点击后,页面会滑动切换到相应模块。 2. **侧滑弹出菜单**:...
本篇将深入探讨一个Android应用源码,该源码旨在模仿UCWEB的界面设计,从而帮助开发者学习和理解如何在Android平台上构建类似的应用。 首先,我们要明确Android应用的基本结构。一个标准的Android项目通常包括以下...
这些组件通常包括但不限于:按钮、输入框、滑动条、下拉列表、切换开关、导航抽屉、底部导航栏、悬浮操作按钮(FAB)、通知提示、日期选择器等。每个组件都尽可能地模仿了Android原生控件的样式和行为,确保在设计时...
【Menu】在Android中,Menu通常用于表示应用程序的主操作选项,如汉堡菜单或底部导航栏。在这个项目中,"Menu"可能被赋予了特殊的设计,利用水波纹动画来增强用户体验。 【MultiWaveHeader】和【lobsterpicker】...
- **底部导航栏**:可能包含一个底部导航条,用于切换相册、拍照、预览等不同模式。 - **选择数量限制**:可以设定最多选择的图片数量,超过则提示用户。 9. **文件操作** - **文件读写**:在用户选择图片后,...
模仿百度贴吧顶部和底部悬浮的效果,效果模仿了在百度过去的几个版本的百度贴吧中的一个界面布局View Layout的效果的,同时该效果特效也可以 实现了悬浮式顶部,还有底部的标题栏的一些常见漂亮的效果,底部的也可以...
**LinearLayout** 是Android中最基础的布局管理器之一,它按照垂直或水平方向将子视图排列成一条线。在LinearLayout中,每个子视图可以设置权重(weight),通过权重分配多余的空间,使得界面元素能根据屏幕尺寸...