我正在尝试创建一个包含两个文本字段的自定义按钮.当我从代码创建实例时,它可以工作.当我尝试从XML充气时,它会崩溃.
到目前为止我尝试解决这个问题:
从我读过的问题来看,最常见的原因是没有定义获取属性集所需的构造函数即
MyClass(Context context, AttributeSet attrs) {
super(context, attrs);
}
Run Code Online (Sandbox Code Playgroud)
在LogCat的错误列表的末尾附近,我有:
Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
Run Code Online (Sandbox Code Playgroud)
这可能会导致我得出与其他许多人一样的错误的结论,但是当你查看下面的代码时,你可以看到我已经定义了这个表单的构造函数.
我似乎完全像所有消息来源所说的那样做.我只是看不到我错过的东西.
SRC/com.soundconception.custombuttontest2/TitledValueButton.java
package com.soundconception.custombuttontest2;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Button;
public class TitledValueButton extends Button {
public TitledValueButton(Context context) {
super(context);
}
protected TitledValueButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
Run Code Online (Sandbox Code Playgroud)
RES /值/ attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TitledValueButton">
<attr name="titleText" format="string" />
</declare-styleable>
</resources>
Run Code Online (Sandbox Code Playgroud)
RES /布局/ activity_main.xml中 …
在Google的应用内结算Trivial Drive示例中,a BroadcastReceiver已注册,可在IabHelper设置成功完成后收听有关更新购买的消息.
然而,作者包括以下注释:
注意:在Activity中注册这个监听器是一个坏主意,但这里完成,因为这是一个SAMPLE.
为什么这个听众这个坏主意呢?
此注释可以在Trivial Drive示例的源代码OnIabSetupFinishedListener中的onCreate方法的定义中找到MainActivity
我正在尝试创建一个Fragment,它有一个公共方法,可以将子Fragment添加到自身.
我一直在阅读可能类似的问题,但到目前为止还没有找到任何帮助.我已将问题简化为如下所示的简单测试应用程序.
一旦fragA添加到主布局,我调用public方法fragA.addFragB()让它为自己添加FragmentClassB的实例,但这会导致测试应用程序崩溃,表明"Activity已被销毁"(请参阅LogCat结尾处后).这是否意味着fragA已经被破坏所以我无法添加fragB它,或者它是否意味着fragB已经被破坏所以我不能添加它fragA?或者它完全意味着什么呢?
MainActivity.java
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragMan = getSupportFragmentManager();
// add Fragment A to the main linear layout
FragmentTransaction fragTrans = fragMan.beginTransaction();
FragmentClassA fragA = new FragmentClassA();
fragTrans.add(R.id.mainLinearLayout, fragA);
fragTrans.addToBackStack("A");
fragTrans.commit();
// get Fragment A to add a Fragment B to itself
fragA.addFragB();
}
}
Run Code Online (Sandbox Code Playgroud)
activity_main.xml中
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" …Run Code Online (Sandbox Code Playgroud) 我想我的问题很常见.我有一个相当大的gradle代码库,我使用产品风格生成自定义版本.这些产品口味通常需要一个或多个类的定制版本src\main\java.
我已经阅读了Gradle文档,并且在查看同一个问题时也遇到了以下问题:
使用Build Flavors - 正确构建源文件夹和build.gradle 为同一类的不同版本构建flavor
我明白为什么你不能src\main\java在你的口味中定义相同的类,但是将类从src\main\java你的产品风格转移到你的产品风味中的解决方案有一个相当大的缺点.当您将类移动src\main\java到最新版本以进行自定义时,您还需要将该类的原始非自定义版本的副本移动到其他所有以前的产品类型中,否则它们将不再构建.
您可能只需要每次从原始文件调整一个或两个不同的类(然后必须将这些类重新分配到flavor目录),但随着时间的推移,移动的类的数量将会生成,剩余的数量src\main\java将减少每个类你必须这样做的时间.最终,大多数类都会有各种风格(即使大多数类都是原件的副本)并且src\main\java几乎是空的,有点打败了整个Gradle构建结构的目的.
此外,您需要保持每次开始新口味时可以克隆的"默认"风格,因此您知道根据原始代码库开始使用所有类.
使用BuildConfig中的字段来定义是否应该使用自定义类:
buildConfigField 'boolean', 'CUSTOM_ACTIVITY_X', 'true'
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用以下代码:
final Intent intent = new Intent();
...
if (BuildConfig.CUSTOM_ACTIVITY_X) {
intent.setClass(ThisActivity.this, CustomActivityX.class);
} else {
intent.setClass(ThisActivity.this, DefaultActivityX.class);
}
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)
每种风味仍然需要一个副本CustomActivityX,但它可以只是一个虚拟的空类,你知道它不会被使用.这意味着您的默认版本的类始终保留在src\main\java.
虽然试图摆脱对其他所有风格的虚拟CustomActivityX的需求,但我已经看过了Class.forName().
例如:
final Class activityX;
if (BuildConfig.CUSTOM_ACTIVITY_X) {
try {
activityX = Class.forName("CustomActivityX");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else …Run Code Online (Sandbox Code Playgroud) Android API文档在谈论"远程对象"时意味着什么?
例如,IBinder状态的API文档:
此接口描述了与远程对象交互的抽象协议.
但我已经搜索过,似乎无法找到任何定义,例如"远程对象是一个对象......等等......等等......"
我正在尝试为我的应用实施应用内结算功能.
我正在关注谷歌的TriviaDrive示例应用程序中使用的实现,以及开发人员网站上的相关文档.
我的代码按预期工作,但当我尝试"查询可供购买的项目"时,生成的Inventory对象包含0个对象,即使我已经创建了一个产品.
我paid_version使用Google Play开发者控制台创建了一个带有ID的托管产品,如下图所示:

文档指出"要检索产品详细信息,请调用queryInventoryAsync(boolean, List, QueryInventoryFinishedListener)IabHelper实例."
在我自己的代码中,我调用
mHelper.queryInventoryAsync(true, iabItemSkus, mQueryFinishedListener)
where:
mHelper我的IabHelper实例
iabItemSkus是一个包含单个项目的List,值为"paid_version"
mQueryFinishedListener是我在下面定义的监听器.
IabHelper.QueryInventoryFinishedListener mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
if (result.isFailure()) {
Log.d(TAG, "Querying Inventory Failed: " + result);
return;
}
Log.d(TAG, "Title: " + inv.getSkuDetails(SKU_PAID).getTitle());
Log.d(TAG, "Description: " + inv.getSkuDetails(SKU_PAID).getDescription());
Log.d(TAG, "Price = " + inv.getSkuDetails(SKU_PAID).getPrice());
}
};
Run Code Online (Sandbox Code Playgroud)
但是在调试时我可以看到该Inventory对象在QueryInventoryFinishedListener包含0项中传回,因此调用会inv.getSkuDetails(SKU_PAID).getTitle()给出一个空指针异常.
我无法解决我出错的地方.我期待该Inventory对象包含我paid_version …
我正在RecyclerView中的项目之间实现片段转换动画,以及显示所单击项目的详细信息的片段.换句话说,比较常见......
"点击列表中的卡片,它会扩展到详细视图,而列表的其余部分消失"
...之类的事情.
从RecyclerView项目到详细视图的转换工作正常.项目的共享元素正在转换到新状态,而其余的RecyclerView项目则逐渐消失.
但是,当弹出BackStack时,共享元素会转换回旧状态,但其他RecyclerView项目不会淡入.它们会立即出现在动画的开头,正如您在此屏幕视频中看到的那样
该活动处理了相当多的片段,因此我使用以下通用方法进行事务处理:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void setFragment(int fragId, Bundle args, List<Pair> transitionViews,
String tag, int containerId) {
// Setup the new fragment and transaction
Fragment newFragment = FragmentFactory.newFragment(fragId, args);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(containerId, newFragment, tag);
fragmentTransaction.addToBackStack(tag);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && transitionViews != null) {
// Add the shared elements
for (int i = 0; i < transitionViews.size(); i++) {
final Pair pair = transitionViews.get(i);
fragmentTransaction.addSharedElement((View) pair.first, (String) pair.second);
}
// Setup the transitions …Run Code Online (Sandbox Code Playgroud) 我正在使用In-App Billing V3.
当我尝试购买时,我得到的服务器响应代码为2.
我已经搜索过,但是找不到有关此响应代码含义的文档.
如果您查看官方的应用内结算参考(IAB版本3)文档,您会注意到服务器响应代码表中明显缺少值2.
这个值表示什么,为什么我会得到它?
更新:
我刚刚注意到应用内结算V2的文档说值为2"表示网络连接已关闭".我猜这在V3中是一样的,但文档中只有一个遗漏?任何人都可以确认吗?
更新2:
看起来应用程序结算V3文档最终已更新,以包含缺少的服务器响应.
BILLING_RESPONSE_RESULT_SERVICE_UNAVAILABLE 2 Network connection is down
Run Code Online (Sandbox Code Playgroud) 我创建了一个扩展ViewGroup的类.此MyCustomViewGroup类的一个功能是充当嵌套类MyButton的容器,该类扩展了Button.
我以正常方式从自定义AttributeSet设置MyCustomViewGroup的自定义属性.其中一个属性定义StateListDrawable以用于MyButton嵌套类的实例的背景.我将它存储在类变量mMyButtonBackground中.
public class MyCustomViewGroup extends ViewGroup {
private Drawable mMyButtonBackground;
...
Run Code Online (Sandbox Code Playgroud)
每次我在MyCustomViewGroup中创建MyButton的新实例时,我都会设置它的背景.
MyButton myButton = new MyButton(context);
myButton.setBackground(mMyButtonBackground);
Run Code Online (Sandbox Code Playgroud)
在运行时,StateListDrawable似乎只适用于最近添加的MyButton实例.
例如,假设我在MyCustomViewGroup中创建了4个MyButton实例.如果我单击MyButton number 4,它的背景会发生变化,如StateListDrawable中所定义.如果我点击MyButton 1到3,他们的背景不会改变,但MyButton编号为4.
从逻辑上讲,这表明它是一个可变性问题.所有MyButton实例共享存储在mMyButtonBackground中的相同StateListDrawable.考虑到这一点,我尝试过:
MyButton myButton = new MyButton(context);
Drawable myButtonBackground = mMyButtonBackground.mutate();
myButton.setBackground(myButtonBackground);
Run Code Online (Sandbox Code Playgroud)
但这并没有解决问题.我也试过将它专门用作StateListDrawable:
MyButton myButton = new MyButton(context);
StateListDrawable myButtonBackground = (StateListDrawable)mMyButtonBackground.mutate();
myButton.setBackground(myButtonBackground);
Run Code Online (Sandbox Code Playgroud)
这也没有解决问题.在我试图解决这个问题的研究中,我已经阅读了Romain Guy关于Drawable突变的这篇文章.我原以为,由于StateListDrawable是Drawable的子类,我应该可以应用相同的方法,但我似乎无法让它工作.我错过了什么?
我正在构建一个自定义复合控件.该复合控件的一个组件是自定义按钮.我的ShiftingTabButton是我的复合控件类中的嵌套类.
我需要将ShiftingTabButton的clipBounds设置为略短于首次绘制时的实际高度.
在下面显示的ShiftingTabButton构造函数中,我设置了一些必要的参数,然后measure()使用mode 调用UNSPECIFIED,以确定新视图的预期大小.当我在调试模式下运行时,我可以看到width= 160和height= 64我的Nexus 7.
到目前为止都很好.
但是当我尝试使用修改后的clipBounds调用setClipBounds()时,应用程序崩溃了.
我已经尝试useShorterClipBounds在构造函数中定义一个标志,将方法的设置移动clipBounds到onDraw()方法并使其依赖于标志检查,但我仍然得到同样的崩溃.
public ShiftingTabButton(Context context, String string) {
super(context);
// parameter setup
this.setText(string);
this.setBackground(getResources().getDrawable(R.drawable.tab_unselected));
this.setId(generateChildViewId());
this.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
this.setPadding(dpToPx(7), 0, dpToPx(7), 0);
// measure the view
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED);
this.measure(widthMeasureSpec, heightMeasureSpec);
int width = this.getMeasuredWidth();
int height = this.getMeasuredHeight();
// adjust the clipBounds
Rect clipBounds = new Rect();
clipBounds.set(0, 0, width, height …Run Code Online (Sandbox Code Playgroud) 该方法的预期目的是findBinding(View view)什么?
我一直在使用数据绑定库测试版。
目前还没有针对各个类的官方参考文档,因此我一直在查看源代码以查看我们可以访问哪些方法。
DataBindingUtil 类有两个方法,听起来它们会做类似的事情:
public static <T extends ViewDataBinding> T findBinding(View view)public static <T extends ViewDataBinding> T getBinding(View view)第二种方法getBinding只是一个调用ViewDataBinding类getBinding方法的实用方法。
第一种方法findBinding不太清楚遵循和确定其目的。有任何想法吗?
我正在创建一个自定义ViewGroup.如果我将自定义ViewGroup添加到布局而未指定LayoutParams(如下所示),则会正确显示:
...
MyCustomViewGroup myViewGroup = new MyCustomViewGroup(this);
myRelativeLayout.addView(myViewGroup);
...
Run Code Online (Sandbox Code Playgroud)
如果我指定LayoutParams并将宽度设置为MATCH_PARENT并将高度设置为WRAP_CONTENT(如下所示),则不会显示:
...
MyCustomViewGroup myViewGroup = new MyCustomViewGroup(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
myRelativeLayout.addView(myViewGroup, params);
...
Run Code Online (Sandbox Code Playgroud)
我为两种方案都运行了Debug.
场景1
如果我没有指定任何LayoutParams,则子视图会正确测量,当方法遍历所有子视图以确定最大高度时,child.getMeasuredHeight()每次都返回正确的值.
场景2
如果我指定LayoutParams的宽度为MATCH_PARENT,高度为WRAP_CONTENT,则系统会通过onMeasure执行两次传递,如下所述.
传递1
widthSpecMode = EXACTLY
width = widthSpecSize = 758这是父RelativeRayout的宽度
heightSpecMode = EXACTLY
height = heightSpecSize = 1055这是父RelativeLayout的高度
传递2
widthSpecMode = EXACTLY
width = widthSpecSize = 758这是父RelativeRayout的宽度
heightSpecMode = AT_MOST
该方法然后迭代所有子视图以确定最大高度,但child.getMeasuredHeight()每次返回0.
子视图有几个ImageButtons和一个TextView.它们都有内容,并且在第一个场景中正确显示了内容.为什么在第二种情况下它的高度为0,我该如何解决呢?
`' 我写了一个简化的测试应用程序来重现问题.所有必要的代码如下所示.如果有人想尝试,你可以简单地剪切和粘贴.
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) …Run Code Online (Sandbox Code Playgroud) android ×12
api-doc ×1
data-binding ×1
google-play ×1
gradle ×1
nested ×1
onmeasure ×1
viewgroup ×1