Joh*_*nha 18 java android android-activity
我已经查看了其他问题,博客和文档,似乎无法找到满足我需求的正确答案.我有两个活动,A和B.当我启动活动B(来自A)时,我希望它立即打开,然后在显示进度条时加载所有内容,而不是仅在加载内容时打开活动,使其成为可能好像它冻结了两秒钟.例如Youtube应用程序或Play商店.
这就是我得到的:
Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent goB = new intent(ActivityA.this, ActivityB.class);
startActivity(goB);
}
});
Run Code Online (Sandbox Code Playgroud)
这是我正在加载的活动:
public class ActivityB extends AppCompatActivity implements OnDateSelectedListener, OnMonthChangedListener {
private static final DateFormat FORMATTER = SimpleDateFormat.getDateInstance();
@Bind(R.id.calendarView) MaterialCalendarView widget;
@Bind(R.id.textView) TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_c_calendar);
ButterKnife.bind(this);
widget.setOnDateChangedListener(this);
widget.setOnMonthChangedListener(this);
textView.setText(getSelectedDatesString());
}
@Override
public void onDateSelected(@NonNull MaterialCalendarView widget, @Nullable CalendarDay date, boolean selected) {
textView.setText(getSelectedDatesString());
}
private String getSelectedDatesString() {
CalendarDay date = widget.getSelectedDate();
if (date == null) {
return "No Selection";
}
return FORMATTER.format(date.getDate());
}
@Override
public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {
}
}
Run Code Online (Sandbox Code Playgroud)
我不是专家,所以欢迎详细的解释.
注意:我在活动中加载的是这个calandar:https://github.com/prolificinteractive/material-calendarview
问题:如何setContentView()
在后台加载?
更新:我遵循了Hitesh Sahu的建议,现在我只有一个活动,其中一个容器被替换为每个片段,我假设在后台加载xml内容的方式对于片段和活动是相同的,但是如果有任何不同,请提及.
您需要AsyncTask
用于加载数据和RelativeLayout
在ActivityB
.
首先初始化变量
private RelativeLayout mRelativeLayout;
Run Code Online (Sandbox Code Playgroud)
在onCreate
你的活动中AsyncTask
像这样执行
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRelativeLayout = (RelativeLayout) findViewbyID(R.id.loadingCircle);
new PrepareData().execute();
}
Run Code Online (Sandbox Code Playgroud)
把这个AsyncTask
类放在ActivityB
private class PrepareData extends AsyncTask<Void, Void, Void> {
protected void onPreExecute(Void param) {
// THIS WILL DISPLAY THE PROGRESS CIRCLE
mRelativeLayout.setVisibility(View.VISIBLE)
}
protected Void doInBackground(Void... param) {
// PUT YOUR CODE HERE TO LOAD DATA
return null;
}
protected void onPostExecute(Void param) {
// THIS WILL DISMISS CIRCLE
mRelativeLayout.setVisibility(View.GONE)
}
Run Code Online (Sandbox Code Playgroud)
并XML
包含此布局
为了获得ProgressBar
无对话框是使用这个
<RelativeLayout
android:id="@+id/loadingCircle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:gravity="center" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
并设置这个的可见性RelativeLayout
在onPreExecute
与onPostExecute
分别像我已经示例中所示。
更新:
你需要更新你Ui
在UiThread
这样的
runOnUiThread(new Runnable() {
@Override
public void run() {
//put the code here that is giving exception
}
});
Run Code Online (Sandbox Code Playgroud)
您的活动 B 应该有用于加载数据然后显示它的 AsyncTask。您也可以在视图中加载一些默认数据OnPreExecute()
@Override
protected void onCreate(Bundle savedInstanceState) {
setupViews();
}
private void setupViews(){
someView1 = (TextView) findViewById(R.id.some_view_id1);
someView2 = (TextView) findViewById(R.id.some_view_id2);
someView3 = (ImageView) findViewById(R.id.some_view_id3);
progressBar = (ProgressBar) findViewById(R.id.progress_bar_id);
new LoadDataForActivity().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private class LoadDataForActivity extends AsyncTask<Void, Void, Void> {
String data1;
String data2;
Bitmap data3;
@Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected Void doInBackground(Void... params) {
data1 = loadData1();
data2 = loadData2();
data3 = loadData3();
}
@Override
protected void onPostExecute(Void result) {
someView1.setText(data1);
someView2.setText(data2);
someView3.setImageBitmap(data3);
progressBar.setVisibility(View.GONE);
}
}
Run Code Online (Sandbox Code Playgroud)
可能的解决方案
根据“我不是专家”的猜测,您可能会在每次屏幕切换时创建新活动,并且可能不会清除较旧的活动或重用现有活动。同样,这是我的猜测,我没有看到您的代码,但是我看到开发人员犯了这种错误。很快,您的App的性能会随着时间的流逝而下降,并且最终您的App将会消耗内存。
如何解决此问题:- 用片段交换片段替换活动比交换活动相对要快,而且您可以重用它们(更多有关此内容)。
您可能在Main Ui线程上做了一些繁重的任务,以寻找编舞者日志,例如-skipped n number of frames app may be doing too much work on main thread
如何解决此问题: -已在其他答案中进行了解释。
小智 1
只需输入这段代码:
Intent goB = new intent(ActivityA.this, ActivityB.class);
startActivity(goB);
Run Code Online (Sandbox Code Playgroud)
在A的onCreate. 然后创建一个 ProgressDialog,如下所示:http ://www.tutorialspoint.com/android/android_progressbar.htm
这将显示 B 加载的进度。你会打电话
progress.setProgress(int)
Run Code Online (Sandbox Code Playgroud)
在B的onCreate中,做某事之后。
例如:
public class B extends Activity {
public void onCreate(Bundle bundle) {
progress=new ProgressDialog(this);
progress.setMessage("Downloading Music");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setIndeterminate(true);
progress.setProgress(0);
progress.show();
//do something
progress.setProgress(1);
//do something
progress.setProgress(2);
//do something different
progress.setProgress(3);
}
.....
Run Code Online (Sandbox Code Playgroud)
编辑
以下是使用 ProgressBar 的方法:
ProgressBar
到 B 布局ProgressBar
在 B 中获取对此的引用onCreate
(使用findViewById()
ProgressBar
每次需要时更新您的setProgress(int)
(如问题的第一部分所示ProgressDialog
)ProgressBar
使用你的ProgressBar.setVisibility(View.GONE)