使用 AppCompat v22.1.0 时如何在 super.onCreate 之前设置 ContentView?
How to setContentView before super.onCreate while using AppCompat v22.1.0?
嘿,我刚刚将我的应用程序升级到 AppCompat v22.1.0 并遇到了这个异常
Caused by: java.lang.IllegalArgumentException: AppCompat does not support the current theme features
at android.support.v7.app.AppCompatDelegateImplV7.ensureSubDecor(AppCompatDelegateImplV7.java:360)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:246)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
我找到了解决方案。这里
问题仍然没有解决,因为我在 super.onCreate 之后调用了 setContentView,在 ConnectionWifiEditActivity
Class.
当我更改它时它抛出 NullPointerException
我该如何解决这个问题?
Caused by: java.lang.NullPointerException
at Client.Activity.connection.ConnectionEditActivity.onResume(ConnectionEditActivity.java:46)
at Client.Activity.connection.ConnectionWifiEditActivity.onResume(ConnectionWifiEditActivity.java:81)
ConnectionWifiEditActivity
public class ConnectionWifiEditActivity extends ConnectionEditActivity implements OnClickListener
{
private ConnectionWifi connection;
private EditText host;
private EditText port;
Button scan;
ListView lv;
private Toolbar mToolbar;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.connectionwifiedit);
lv = (ListView) findViewById(android.R.id.list);
this.connection = (ConnectionWifi) connectionParam;
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
this.host = (EditText) this.findViewById(R.id.host);
this.port = (EditText) this.findViewById(R.id.port);
SnackbarManager.show(
Snackbar.with(getApplicationContext()) // context
.type(SnackbarType.MULTI_LINE) // Set is as a multi-line snackbar
.text(R.string.tip) // text to be displayed
.duration(Snackbar.SnackbarDuration.LENGTH_INDEFINITE)
, this);
}
public void Save(View v){
this.finish();
}
@Override
public void onClick(View v)
{
}
protected void onResume()
{
super.onResume();
this.host.setText(this.connection.getHost());
this.port.setText(Integer.toString(this.connection.getPort()));
}
protected void onPause()
{
super.onPause();
this.connection.setHost(this.host.getText().toString());
this.connection.setPort(Integer.parseInt(this.port.getText().toString()));
}}
ConnectionEditActivity
public static Connection connectionParam;
private Connection connection;
private EditText name;
private EditText password;
public class ConnectionEditActivity extends AppCompatActivity implements OnClickListener
{
public static Connection connectionParam;
private Connection connection;
private Button save;
private EditText name;
private EditText password;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
}
protected void onResume()
{
super.onResume();
this.name.setText(this.connection.getName());
this.password.setText(this.connection.getPassword());
}
protected void onPause()
{
super.onPause();
this.connection.setName(this.name.getText().toString());
this.connection.setPassword(this.password.getText().toString());
}
public void onClick(View v)
{
if (v == this.save)
{
this.finish();
}
}
}
连接
public abstract class Connection implements Comparable<Connection>, Serializable
{
private static final long serialVersionUID = 1L;
public static final int TYPE_COUNT = 2;
public static final int WIFI = 0;
public static final int BLUETOOTH = 1;
private String name;
private String password;
public Connection()
{
this.name = "";
this.password = RemoteItConnection.DEFAULT_PASSWORD;
}
public static Connection load(SharedPreferences preferences, ConnectionList list, int position)
{
Connection connection = null;
int type = preferences.getInt("connection_" + position + "_type", -1);
switch (type)
{
case WIFI:
connection = ConnectionWifi.load(preferences, position);
break;
case BLUETOOTH:
connection = ConnectionBluetooth.load(preferences, position);
break;
}
connection.name = preferences.getString("connection_" + position + "_name", null);
connection.password = preferences.getString("connection_" + position + "_password", null);
return connection;
}
public void save(Editor editor, int position)
{
editor.putString("connection_" + position + "_name", this.name);
editor.putString("connection_" + position + "_password", this.password);
}
public abstract RemoteItConnection connect(RemoteIt application) throws IOException;
public abstract void edit(Context context);
protected void edit(Context context, Intent intent)
{
ConnectionEditActivity.connectionParam = this;
context.startActivity(intent);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public int compareTo(Connection c)
{
return this.name.compareTo(c.name);
}
}
只需将此添加到您的样式中(两者都需要)
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
在 ConnectionEditActivity 中,您在调用 setContentView 之前调用 findViewById,它将始终 return null。所以你的观点将永远是空的。
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
既然要在super方法中获取一些ui元素,就得想办法在superclass中定义布局。这是因为您正在获得其他答案中所述的 NPE。
你可以在supersetContentView()
中使用class,使用一个方法来return布局来使用。
这样你就可以在子class中重写布局,重写方法
例如,您可以使用 setContentView(getLayoutId()):
public class ConnectionEditActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(getLayoutId()); //pay attention here...
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
}
protected int getLayoutId(){
//....
}
}
你可以在其他 activity 中覆盖它,在那里你可以避免 setContentView
方法。
public class ConnectionWifiEditActivity extends ConnectionEditActivity{
@Override
protected int getLayoutId(){
return R.layout.connectionwifiedit;
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(); //comment this line
//..
}
}
小技巧是在您的父级中使用 override fun onPostCreate(savedInstanceState: Bundle?)
方法来查找视图
嘿,我刚刚将我的应用程序升级到 AppCompat v22.1.0 并遇到了这个异常
Caused by: java.lang.IllegalArgumentException: AppCompat does not support the current theme features
at android.support.v7.app.AppCompatDelegateImplV7.ensureSubDecor(AppCompatDelegateImplV7.java:360)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:246)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
我找到了解决方案。这里
问题仍然没有解决,因为我在 super.onCreate 之后调用了 setContentView,在 ConnectionWifiEditActivity
Class.
当我更改它时它抛出 NullPointerException
我该如何解决这个问题?
Caused by: java.lang.NullPointerException
at Client.Activity.connection.ConnectionEditActivity.onResume(ConnectionEditActivity.java:46)
at Client.Activity.connection.ConnectionWifiEditActivity.onResume(ConnectionWifiEditActivity.java:81)
ConnectionWifiEditActivity
public class ConnectionWifiEditActivity extends ConnectionEditActivity implements OnClickListener
{
private ConnectionWifi connection;
private EditText host;
private EditText port;
Button scan;
ListView lv;
private Toolbar mToolbar;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.connectionwifiedit);
lv = (ListView) findViewById(android.R.id.list);
this.connection = (ConnectionWifi) connectionParam;
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
this.host = (EditText) this.findViewById(R.id.host);
this.port = (EditText) this.findViewById(R.id.port);
SnackbarManager.show(
Snackbar.with(getApplicationContext()) // context
.type(SnackbarType.MULTI_LINE) // Set is as a multi-line snackbar
.text(R.string.tip) // text to be displayed
.duration(Snackbar.SnackbarDuration.LENGTH_INDEFINITE)
, this);
}
public void Save(View v){
this.finish();
}
@Override
public void onClick(View v)
{
}
protected void onResume()
{
super.onResume();
this.host.setText(this.connection.getHost());
this.port.setText(Integer.toString(this.connection.getPort()));
}
protected void onPause()
{
super.onPause();
this.connection.setHost(this.host.getText().toString());
this.connection.setPort(Integer.parseInt(this.port.getText().toString()));
}}
ConnectionEditActivity
public static Connection connectionParam;
private Connection connection;
private EditText name;
private EditText password;
public class ConnectionEditActivity extends AppCompatActivity implements OnClickListener
{
public static Connection connectionParam;
private Connection connection;
private Button save;
private EditText name;
private EditText password;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
}
protected void onResume()
{
super.onResume();
this.name.setText(this.connection.getName());
this.password.setText(this.connection.getPassword());
}
protected void onPause()
{
super.onPause();
this.connection.setName(this.name.getText().toString());
this.connection.setPassword(this.password.getText().toString());
}
public void onClick(View v)
{
if (v == this.save)
{
this.finish();
}
}
}
连接
public abstract class Connection implements Comparable<Connection>, Serializable
{
private static final long serialVersionUID = 1L;
public static final int TYPE_COUNT = 2;
public static final int WIFI = 0;
public static final int BLUETOOTH = 1;
private String name;
private String password;
public Connection()
{
this.name = "";
this.password = RemoteItConnection.DEFAULT_PASSWORD;
}
public static Connection load(SharedPreferences preferences, ConnectionList list, int position)
{
Connection connection = null;
int type = preferences.getInt("connection_" + position + "_type", -1);
switch (type)
{
case WIFI:
connection = ConnectionWifi.load(preferences, position);
break;
case BLUETOOTH:
connection = ConnectionBluetooth.load(preferences, position);
break;
}
connection.name = preferences.getString("connection_" + position + "_name", null);
connection.password = preferences.getString("connection_" + position + "_password", null);
return connection;
}
public void save(Editor editor, int position)
{
editor.putString("connection_" + position + "_name", this.name);
editor.putString("connection_" + position + "_password", this.password);
}
public abstract RemoteItConnection connect(RemoteIt application) throws IOException;
public abstract void edit(Context context);
protected void edit(Context context, Intent intent)
{
ConnectionEditActivity.connectionParam = this;
context.startActivity(intent);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public int compareTo(Connection c)
{
return this.name.compareTo(c.name);
}
}
只需将此添加到您的样式中(两者都需要)
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
在 ConnectionEditActivity 中,您在调用 setContentView 之前调用 findViewById,它将始终 return null。所以你的观点将永远是空的。
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
既然要在super方法中获取一些ui元素,就得想办法在superclass中定义布局。这是因为您正在获得其他答案中所述的 NPE。
你可以在supersetContentView()
中使用class,使用一个方法来return布局来使用。
这样你就可以在子class中重写布局,重写方法
例如,您可以使用 setContentView(getLayoutId()):
public class ConnectionEditActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(getLayoutId()); //pay attention here...
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
}
protected int getLayoutId(){
//....
}
}
你可以在其他 activity 中覆盖它,在那里你可以避免 setContentView
方法。
public class ConnectionWifiEditActivity extends ConnectionEditActivity{
@Override
protected int getLayoutId(){
return R.layout.connectionwifiedit;
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(); //comment this line
//..
}
}
小技巧是在您的父级中使用 override fun onPostCreate(savedInstanceState: Bundle?)
方法来查找视图