- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有以下类(class):
class SlidingTabStrip extends LinearLayout {
private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 1;
private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 3;
private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
private final int mBottomBorderThickness;
private final Paint mBottomBorderPaint;
private final int mSelectedIndicatorThickness;
private final Paint mSelectedIndicatorPaint;
private final int mDefaultBottomBorderColor;
private int mSelectedPosition;
private float mSelectionOffset;
private SlidingTabLayout.TabColorizer mCustomTabColorizer;
private final SimpleTabColorizer mDefaultTabColorizer;
SlidingTabStrip(Context context) {
this(context, null);
}
SlidingTabStrip(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);
final float density = getResources().getDisplayMetrics().density;
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(Color.parseColor("#000000"), outValue, true);
final int themeForegroundColor = outValue.data;
mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
mDefaultTabColorizer = new SimpleTabColorizer();
mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
mBottomBorderPaint = new Paint();
mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
mSelectedIndicatorPaint = new Paint();
}
void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
mCustomTabColorizer = customTabColorizer;
invalidate();
}
void setSelectedIndicatorColors(int... colors) {
// Make sure that the custom colorizer is removed
mCustomTabColorizer = null;
mDefaultTabColorizer.setIndicatorColors(colors);
invalidate();
}
void onViewPagerPageChanged(int position, float positionOffset) {
mSelectedPosition = position;
mSelectionOffset = positionOffset;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
final int height = getHeight();
final int childCount = getChildCount();
final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null ? mCustomTabColorizer : mDefaultTabColorizer;
// Thick colored underline below the current selection
if (childCount > 0) {
View selectedTitle = getChildAt(mSelectedPosition);
int left = selectedTitle.getLeft();
int right = selectedTitle.getRight();
int color = tabColorizer.getIndicatorColor(mSelectedPosition);
if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
if (color != nextColor) {
color = blendColors(nextColor, color, mSelectionOffset);
}
// Draw the selection partway between the tabs
View nextTitle = getChildAt(mSelectedPosition + 1);
left = (int) (mSelectionOffset * nextTitle.getLeft() +
(1.0f - mSelectionOffset) * left);
right = (int) (mSelectionOffset * nextTitle.getRight() +
(1.0f - mSelectionOffset) * right);
}
mSelectedIndicatorPaint.setColor(color);
canvas.drawRect(left, height - mSelectedIndicatorThickness, right,height, mSelectedIndicatorPaint);
}
// Thin underline along the entire bottom edge
canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
}
/**
* Set the alpha value of the {@code color} to be the given {@code alpha} value.
*/
private static int setColorAlpha(int color, byte alpha) {
return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
}
/**
* Blend {@code color1} and {@code color2} using the given ratio.
*
* @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
* 0.0 will return {@code color2}.
*/
private static int blendColors(int color1, int color2, float ratio) {
final float inverseRation = 1f - ratio;
float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
return Color.rgb((int) r, (int) g, (int) b);
}
private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
private int[] mIndicatorColors;
@Override
public final int getIndicatorColor(int position) {
return mIndicatorColors[position % mIndicatorColors.length];
}
void setIndicatorColors(int... colors) {
mIndicatorColors = colors;
}
}
}
下面一行用来在tabstrip下面画一条线:
canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
如果我设置如下:
private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 10;
我得到一行看起来像:
但是我想把它画在标签条之外,比如:
有什么提示和指南可以实现吗?
好的,按照 Rod 的建议,我尝试使用 FrameLayout:
<?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:orientation="vertical" >
<!-- android:paddingTop="?android:attr/actionBarSize" -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="@drawable/bottom_shadow" >
<com.example.SlidingTabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/actionbar_bg" />
</FrameLayout>
<!--
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:windowContentOverlay" />
-->
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="@android:color/white" />
</LinearLayout>
通过这种技术,我得到的结果是:
最佳答案
实际上,您不能使用 OnDraw
在选项卡中添加下拉阴影。
你需要做的是将你的内容包装在 FrameLayout
中并使用它的 android:foreground
并设置一个可以在 Material 设计图标中找到的阴影图像在它上面模拟一个阴影。
这是一个九补丁图像。确保如果你使用它,它应该位于你的 xhdpi 可绘制文件夹中,扩展名为 name.9.png
用于添加上述图像以在 View 顶部模拟阴影的示例 xml:
<FrameLayout
android:id="@+id/fl_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tool_bar"
android:foreground="@drawable/bottom_shadow">
// your view here
</FrameLayout>
编辑:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="@drawable/bottom_shadow" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="@android:color/white" />
</FrameLayout>
关于android - 5.1 like elevation Shadow under a View using onDraw 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29816179/
安卓游戏用什么比较好: 一个带有渲染线程的SurfaceView 或 一个 SurfaceView,带有调用 SurfaceView 函数的线程 doDraw() 谢谢。 最佳答案 SurfaceVi
我花了一整天的时间调试各种将自定义 ViewGroup 添加到另一个自定义 ViewGroup 的方法,但几乎要疯了,因为它们都不起作用,而且没有官方文档或显示如何完成的示例... 基本上,我有 2
我正在尝试创建一个简单的应用程序,绘制一个简单的图形,然后单击按钮后对图形进行一些仿射变换。你能帮我完成 onClick 方法旋转吗?万分感谢。问题是,如果可能的话,我不知道如何从 CanvasVie
我有一个简单的图形应用程序,可以在屏幕上绘制一些内容。之前,我在 onDraw() 中调用 invalidate() 时没有进行检查,没有任何问题。在我的应用程序中, onDraw() 每秒被调用多次
这个问题已经有答案了: Is Java "pass-by-reference" or "pass-by-value"? (91 个回答) 已关闭 9 年前。 我提到了this question但它没有
我有以下代码: @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setCo
我的自定义 View 的 onDraw() 没有被触发。为什么?我正在使用 2.3.3。 View 创建时不应该自动绘制吗? onMeasure() 方法被触发,我得到正确的屏幕宽度和高度。 pack
我正在处理我的 ondraw 方法无法正常工作的应用程序......在我的应用程序中,我正在使用 framelayout ...所以我用了三级...1)活跃度2)图像选择3)绘图 我的图像选择工作正常
我有一个 SurfaceView,我喜欢在其中绘制一堆文本并绘制 72px x 72px 的 png 图像。图像始终绘制在 SurfaceView 上,但每 2 秒在不同的位置绘制一次。 (从该图
在我的自定义绘制 View 中,我使用了 Canvas.drawPaint(Paint) 方法。但 Android Studio 中的预览显示此消息: The graphics preview in
我创建了一个调用 DrawView extends View 的 Activity ,我在 Canvas 上绘制类似于二叉树的东西。 Canvas 尺寸大于屏幕尺寸,onDraw 函数绘制整个 Can
我试图在按下 drawCircle() 时调用 onDraw()。我知道它正在被调用(通过 xml 中的 onClick),因为我收到消息:“drawCircle pressed”。然而,问题是 in
我用一个新类覆盖了 RelativeLayout 类: public class myRelative extends RelativeLayout{ //... //this function is
我在使用 Android 应用程序时遇到问题。 我有一个线程不断迭代列表或形状,更新它们的位置,有时还会从列表中删除一个项目。在线程的 while 循环结束时,它调用 postInvalidate()
我有一个应用程序可以根据人的生日绘制行星和星座。我在自定义 View 中使用 onDraw() 方法,该方法被添加到 XML 中的 FrameLayout。问题是,当我离开页面并调整日期时,该 Act
我正在尝试在 CScrollView 派生类中显示图像: C++ CScrollView, how to scroll an image? 所以我想覆盖OnDraw,将代码从OnPaint 移动到On
我想向 itemView 添加动画,但是它们仅在项目当前正在移动时运行。例如,项目开始淡出,直到 alpha 为 0,但如果项目停止移动,动画就会暂停,项目只会淡出一半。之后,该项目需要再次开始移动才
对于 Android canvas 游戏,我使用以下(最小化)方法请求重绘 SurfaceView: private void refreshView() { c = surf
我正在使用 Android 2.2 构建游戏。主游戏 Activity 使用自定义 SurfaceView: class GameView extends SurfaceView 据我了解,onDra
我的自定义按钮有问题。 onDraw() 被一次又一次地调用,我不明白为什么。 public class CircleButton extends Button { static final
我是一名优秀的程序员,十分优秀!