我正在制作一个我想在多个笔尖中使用的自定义小部件.所以我创建一个新的视图nib Screen3,添加一些按钮,现在想要我的UIAwesomeSauce小部件.
如果我只是添加一个视图然后更改类标识,它就不会从UIAwesomeSauce笔尖获取子元素.如果我去图书馆并切换到Classes,也是一样的.似乎只有UIViewController具有"从笔尖加载"字段,这将是美丽的.
我知道我可以从代码中加载UIAwesomeSauce笔尖,获取顶级对象,然后手动放置它.但IB的观点是,您不必将代码置于代码中.如果我能让UIAwesomeSauce显示在图书馆列表中,那就更好了.
解决 - 由尼姆罗德 - 阅读解释和代码
无论如何,dood,那太好了.我现在可以制作自己的小部件类,用于愚蠢的真棒.让您的UI的FileOwner成为您的类,并在其中只有一个普通的UIView与您的所有东西.(小部件的nib中的单个视图不能是类本身,或者你在initWithCoder中得到递归.)然后在你要使用它的nib中,创建一个vanilla UIView并更改它的类.你将无法真正看到该广场内的小部件,而是处理.
Self现在是一个空白视图,而tMyActualSelf是您在另一个nib中完成工作的单个视图.好极了!
- (id)initWithCoder:(NSCoder*)coder
{
if ((self = [super initWithCoder:coder]))
{
UIView *tMyActualSelf = nil;
// Initialization code
NSArray *tNibItems = [[NSBundle mainBundle] loadNibNamed:@"UIAwesomeSauce" owner:self options:nil];
for (id object in tNibItems)
{
if ([object isKindOfClass:[UIView class]])
tMyActualSelf = (UIView *)[object retain];
}
if( tMyActualSelf )
{
tMyActualSelf.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[self addSubview:tMyActualSelf];
}
}
return self;
}
Run Code Online (Sandbox Code Playgroud) 我有一组FrameLayout
我想要检查/选择,
也就是说,点击后我希望FrameLayout
显示为checked
- 当再次按下时,我希望它成为联合国checked
.更重要的是,我希望通过使用a来像往常一样描述这个视觉阙<selector>
.
我似乎无法让这个工作 - 我不确定我缺少什么:
public class CheckableFrameLayout extends FrameLayout implements Checkable {
private boolean mChecked = false;
public CheckableFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setChecked(boolean checked) {
mChecked = checked;
refreshDrawableState();
}
public boolean isChecked() {
return mChecked;
}
public void toggle() {
setChecked(!mChecked);
}
}
Run Code Online (Sandbox Code Playgroud)
布局CheckableFrameLayout
:
<com.test.view.CheckableFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/selector_horizontal"
android:clickable="true" >
Run Code Online (Sandbox Code Playgroud)
支持它的选择器(selector_horizontal.xml):
<item android:drawable="@drawable/selector_vertical_selected" android:state_pressed="false" android:state_checked="true"/>
<item android:drawable="@drawable/selector_vertical_pressed" android:state_pressed="true" …
Run Code Online (Sandbox Code Playgroud) 我做了如下
1)创建一个风格
<declare-styleable name="Viewee">
<attr name="linkedView" format="reference"/>
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)
2)定义自定义视图布局
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ffc0">
<TextView
android:id="@+id/custom_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="[text]"
/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
3)创建所需的类
public class Viewee extends LinearLayout
{
public Viewee(Context context, AttributeSet attributeSet)
{
super(context, attributeSet);
View.inflate(context, R.layout.viewee, this);
TextView textView = (TextView) findViewById(R.id.custom_text);
TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.Viewee);
int id = typedArray.getResourceId(R.styleable.Viewee_linkedView, 0);
if (id != 0)
{
View view = findViewById(id);
textView.setText(((TextView) view).getText().toString());
}
typedArray.recycle();
}
}
Run Code Online (Sandbox Code Playgroud)
最后是在下面的活动中
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.ns"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tvTest"
android:layout_width="fill_parent"
android:layout_height="wrap_content" …
Run Code Online (Sandbox Code Playgroud) 是否可以在Android中创建自定义库(具有自己的布局资源),以便在多个Android应用程序中使用?
我创建了一个常规*.jar文件但是当我尝试动态创建/设置我的视图时,大多数属性都不起作用.甚至引用从文件的android.jar简单的风格,如android.attr.listSeparatorTextViewStyle没有工作.
我创建了一个没有任何Activity的Android项目,拥有自己的资源文件,然后从另一个Android项目中引用该项目以在其构建路径中使用.一切似乎工作正常但是当我尝试运行项目时,模拟器不断崩溃(在LogCat中没有有意义的错误消息).
我错过了什么吗?
我遇到了一个令我难过的问题,我希望有人可以给我一些指示.
我正在使用一个使用自定义ViewGroup的应用程序(实际上是一个包含RelativeLayout的FrameLayout)来呈现事件日历.日历中的事件表示为视图,其大小根据事件的持续时间和包含视图的大小而定.
我遇到了调整包含FrameLayout大小时发生的问题.当前实现将删除表示事件的所有视图,并尝试添加新事件并根据FrameLayout的当前大小计算其大小.这项工作是通过View的onSizeChanged()方法触发的,该方法在FrameLayout中被覆盖.
调整视图大小时,将执行此代码并更新视图,但是,它们实际上都不会在屏幕上呈现... FrameLayout中包含的视图根本不可见.如果我在hierarchyviewer工具中加载视图,它们是视图树的一部分,并在概述中列出它们应该位于的位置,但它们不会显示.(请注意,视图在FrameLayout的初始渲染中是可见的......只有在调整大小后它们才会消失.)
看来调整大小期间的事件顺序如下:
onMeasure()
onMeasure()
onSizeChanged()
onLayout()
Run Code Online (Sandbox Code Playgroud)
重置视图后调用requestLayout()(在onSizeChanged()内)似乎没有任何效果.但是,如果在调用requestLayout()之前导致一些延迟,则视图将变为可见.我可以通过生成一个线程和休眠来创建这个延迟,或者通过创建一个虚拟按钮来简单地调用requestLayout()并在调整大小后自己调整它,或者甚至在onSizeChanged()的末尾放置这个丑陋的黑客:
post(new Runnable() {
public void run() {
requestLayout();
}
});
Run Code Online (Sandbox Code Playgroud)
当我使用这个hack时,包含的视图是可见的,事件的顺序如下:
onMeasure()
onMeasure()
onSizeChanged()
onLayout()
onMeasure()
onMeasure()
onLayout()
Run Code Online (Sandbox Code Playgroud)
因此,似乎强制第二个度量传递(在视图树被修改之后)使得包含的视图应该是可见的.为什么延迟对requestLayout()的调用对我来说这是一个谜.
谁能提供任何关于我做错的指示?
我意识到,如果不查看一些代码,这有点难以理解,因此我创建了一个小型示例应用程序,它展示了我的问题并使其在Github上可用:
https://github.com/MichaelSims/ViewGroupResizeTest
我上面提到的hack致力于一个单独的分支:
https://github.com/MichaelSims/ViewGroupResizeTest/tree/post-runnable-hack
如果我能提供任何其他信息,请提前通知我并提前致谢.
package com.binod.customviewtest;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
public class CustomView extends RelativeLayout{
public CustomView(Context context) {
super(context);
// TODO Auto-generated constructor stub
// LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater mInflater = LayoutInflater.from(context);
mInflater.inflate(R.layout.custom_view , this, true);
}
}
Run Code Online (Sandbox Code Playgroud)
包括为
<RelativeLayout 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"
tools:context=".MainActivity" >
<com.binod.customviewtest.CustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
></com.binod.customviewtest.CustomView>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
自定义视图为
<RelativeLayout 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"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
刚刚开始添加新的自定义视图并获得错误一次如果我清除它然后可以继续前进
我正在崩溃"引起:android.view.InflateException:二进制XML文件行#1:错误膨胀类"
我有在我需要绘制两个位图自定义视图,一个是背景,代表了地图的形象,一个是将在画布上/左侧位置绘制的引脚.
这两个图像都是在绘图上绘制的,并且在包含视图的活动的实时期间保持不变.过了一会儿,我得到了一个
OutOfMemoryError:位图大小超过VM预算
这意味着我有泄漏,位图不会被垃圾收集.我之前问过这个问题,但现在情况发生了一些变化.我做了一个init方法,我设置了我想要使用的位图,但这仍然不是一个好方法,错误出现在后面,但仍然存在.
这是代码
public class MyMapView extends View {
private int xPos = 0;
private int yPos = 0;
private int space = 0;
private Bitmap resizedBitmap;
private Bitmap position;
private Bitmap mapBitmap;
public void setMapBitmap(Bitmap value) {
this.mapBitmap = value;
}
public MyMapView(Context context) {
super(context);
}
public MyMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void init(final Context context) {
Paint paint = …
Run Code Online (Sandbox Code Playgroud) 我正在处理日历视图自定义.我正在使用这个库.
我希望在此日历中添加此类uiview.实际上我可以通过长按添加事件(如下面的gif所示),但我想添加这两个点(按钮)来调整事件视图的大小并分别更改事件时序.
我们需要的输出,如您所见:
我的自定义视图具有动态自定义属性,例如backgroundimage属性,通过当前周分配.我不想使用construtor CalendarView(Context context,AttributeSet attrs)来传递几个属性,我尝试使用Xml.asAttributeSet实例化attributeset,但它无法工作.任何人都可以告诉我该怎么做.
注意:我的自定义视图具有动态属性,因此我不想通过xml布局实例化自定义视图.我的解决方案不正确?
这是自定义视图:
public class CalendarView extends View {
int backgroundImage;
public CalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
backgroundImage = attrs.getAttributeResourceValue("http://www.mynamespace.com", "backgroundimage", 0);
}
}
Run Code Online (Sandbox Code Playgroud)
这是活动:
public class TestActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(createTestView(0));
}
public CalendarView createTestView(int currentWeek) throws XmlPullParserException, IOException {
String attributes = "<attribute xmlns:android=\"http://schemas.android.com/apk/res/android\" " +
"xmlns:test=\"http://www.mynamespace.com\" " +
"android:layout_width=\"fill_parent\" android:layout_height=\"30\" " +
"test:backgroundimage=\"@drawable/"+ currentWeek +"_bg" + "\"/>";
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = …
Run Code Online (Sandbox Code Playgroud) 我一直在调整自定义视图的大小和布局问题,我想知道是否有人可以提出"最佳实践"方法.问题如下.想象一下自定义视图,其中内容所需的高度取决于视图的宽度(类似于多行TextView).(显然,这仅适用于布局参数未修复高度的情况.)问题是,对于给定宽度,在这些自定义视图中计算内容高度相当昂贵.特别是,在UI线程上进行计算太昂贵了,因此在某些时候需要启动工作线程来计算布局,并且在完成时,需要更新UI.
问题是,这应该如何设计?我想过几个策略.他们都假设无论何时计算高度,都会记录相应的宽度.
第一个策略显示在此代码中:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
setMeasuredDimension(width, measureHeight(heightMeasureSpec, width));
}
private int measureWidth(int widthMeasureSpec) {
// irrelevant to this problem
}
private int measureHeight(int heightMeasureSpec, int width) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
if (width != mLastWidth) {
interruptAnyExistingLayoutThread();
mLastWidth = width;
mLayoutHeight = DEFAULT_HEIGHT;
startNewLayoutThread();
}
result = mLayoutHeight;
if (specMode == MeasureSpec.AT_MOST && result …
Run Code Online (Sandbox Code Playgroud)