我创建了一个活动,当点击按钮时,它会递归调用自己。
layout
的{{1}}是一个包含三层的嵌套布局,可能会导致性能问题。
要在递归调用方法时禁止Transition-Animations,我按照以下示例添加了代码:StackOverFLow Post
在动画图片中,您可以看到这些黑色不会出现在所有过渡中,而是出现在大多数过渡时。这不仅仅是图像中较低的framrate的结果。问题也只发生在手机上运行时(华为P10表现不错)。
我无法从经验中评估,我的代码是否浪费了太多资源,这也是我添加布局和活动代码的原因。
我还阅读the following question and answers关于使用Activity
方法进行耗时的方法,所以我将7个方法移到那里,但没有成功。
除了不能一遍又一遍地回忆起活动之外,还有什么我可以尝试的吗?
onResume
活动布局:
public class PracticeActivity extends AppCompatActivity {
private static ArrayList<VocCard> vocCardList = null;
private static String listName;
private static int swapStep;
private View mCardFrontLayout;
private View mCardBackLayout;
private AnimatorSet mSetLeftOut;
private AnimatorSet mSetRightIn;
private AnimatorSet mSetRightOut;
private AnimatorSet mSetLeftIn;
private boolean isBackRevealed = false;
private boolean isBackVisible = true;
private int angle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice);
// Get the Intent that started this activity and extract the List
if(vocCardList ==null) {
vocCardList = getIntent().getParcelableArrayListExtra("VocList");
listName = getIntent().getStringExtra("listName");
swapStep = (int) getIntent().getIntExtra("swapStep",0);
if(swapStep <=0){
swapStep = vocCardList.size();
}
}
mCardBackLayout = findViewById(R.id.card_back_frame);
mCardFrontLayout = findViewById(R.id.card_front_frame);
}
@Override
public void onResume(){
super.onResume();
createRandIncline();
loadAnimations();
changeCameraDistance();
makeBackCardInvisible();
adaptCards2ScreenSize();
applyStringsToCard();
setProgressBar();
}
private void setProgressBar() {
int progress = (int) (100/vocCardList.size()*(vocCardList.get(0).getCount()+1));
ProgressBar prBar = (ProgressBar) findViewById(R.id.progress_bar);
prBar.setProgress(progress);
}
private void adaptCards2ScreenSize() {
DisplayMetrics metrics;
metrics = getApplicationContext().getResources().getDisplayMetrics();
FrameLayout frontCard = (FrameLayout) findViewById(R.id.card_front_frame);
FrameLayout backCard = (FrameLayout) findViewById(R.id.card_back_frame);
float density = metrics.density;
int width = metrics.widthPixels;
int height = metrics.heightPixels;
FrameLayout.LayoutParams layoutParamsF = (FrameLayout.LayoutParams) frontCard.getLayoutParams();
layoutParamsF.width = (int) (0.7*width);
layoutParamsF.height = (int) (0.49*width);
frontCard.setLayoutParams(layoutParamsF);
FrameLayout.LayoutParams layoutParamsB = (FrameLayout.LayoutParams) backCard.getLayoutParams();
layoutParamsB.width = (int) (0.7*width);
layoutParamsB.height = (int) (0.49*width);
backCard.setLayoutParams(layoutParamsB);
}
private void makeBackCardInvisible() {
mCardBackLayout.setVisibility(View.INVISIBLE);
isBackVisible = false;
}
private void changeCameraDistance() {
int distance = 5000; // 5000 looks nice
float scale = getResources().getDisplayMetrics().density * distance;
mCardFrontLayout.setCameraDistance(scale);
mCardBackLayout.setCameraDistance(scale);
}
private void loadAnimations() {
mSetLeftOut = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.ani_out_left);
mSetRightIn = (AnimatorSet) AnimatorInflater.loadAnimator(this, R. animator.ani_in_right);
mSetRightOut = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.ani_out_right);
mSetLeftIn = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.ani_in_left);
}
private void createRandIncline() {
Random rand = new Random();
angle = rand.nextInt(31) - rand.nextInt(31); // creates angle between -30° and +30°
mCardBackLayout.setRotation(angle);
mCardFrontLayout.setRotation(-angle);
}
public void wrongContinuePractice(View view) {
vocCardList.get(vocCardList.get(0).getCount()).increaseErrorLevel();
swapCards(swapStep);
Intent intent = new Intent(PracticeActivity.this, PracticeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
}
private void swapCards(int swapStep) {
int count = vocCardList.get(0).getCount();
if((count+swapStep)>= vocCardList.size()){
vocCardList.add(vocCardList.get(count));
vocCardList.remove(count);
}
else {
vocCardList.add(count + swapStep, vocCardList.get(count));
vocCardList.remove(count);
}
}
public void correctContinuePractice(View view) {
VocCard card4count = vocCardList.get(0);
vocCardList.get(card4count.getCount()).decreaseErrorLevel();
if (card4count.getCount() >= vocCardList.size() - 1) {
printResultsToXML();
adjustContentInLOCXML();
//reset VocCard counter
card4count.resetCount();
//set vocCardList to null, because it is static
vocCardList = null;
Intent intent = new Intent(PracticeActivity.this, EndPracticeActivity.class);
startActivity(intent);
} else {
card4count.increaseCount();
Intent intent = new Intent(PracticeActivity.this, PracticeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0,0);
startActivity(intent);
}
}
private void adjustContentInLOCXML() {
File fListColl = new File(getFilesDir().getAbsolutePath()+"/list_of_collections.xml");
String fListColl_path = getFilesDir().getAbsolutePath()+"/list_of_collections.xml";
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(fListColl);
NodeList nListList = doc.getElementsByTagName("List");
int counter = 0;
for(int i = 0; i+counter<nListList.getLength(); i++){
Element thisNode = (Element) nListList.item(i);
String name = thisNode.getAttribute("name");
if(name.equals(listName)) {
counter = nListList.getLength(); //Stop after this loop
NodeList nChildren = thisNode.getChildNodes();
int nChSize = nChildren.getLength();
Log.println(Log.INFO, "children size", String.valueOf(nChSize));
Element eTrainingR = (Element) nChildren.item(5);
String sTrainingRText = eTrainingR.getTextContent();
int iNewTrainingR = Integer.parseInt(sTrainingRText)+1;
eTrainingR.setTextContent(String.valueOf(iNewTrainingR));
Element eError = (Element) nChildren.item(7);
int iErrors = 0;
for(int j = 0; j<vocCardList.size(); j++ ){
if(vocCardList.get(j).getErrorLevel()>0){
iErrors++;
}
}
int iErrorPercent = (int) (100/vocCardList.size()*iErrors);
Log.println(Log.INFO, "Error %", String.valueOf(iErrorPercent));
Element eLearned = (Element) nChildren.item(9);
eError.setTextContent(String.valueOf(iErrorPercent));
eLearned.setTextContent(String.valueOf(100-iErrorPercent));
//Log.println(Log.INFO, "attr name", "name is: " + name);
}
}
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(fListColl_path));
transformer.transform(source, result);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
private void printResultsToXML() {
File currentVocList = new File(getFilesDir().getAbsolutePath()+"/"+listName+".xml");
String currentVocList_path = getFilesDir().getAbsolutePath()+"/"+listName+".xml";
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(currentVocList);
NodeList allVocs = doc.getElementsByTagName("vocabulary");
for(int i = 0; i<vocCardList.size(); i++){
int counter = 0;
for(int j = 0; j+counter<allVocs.getLength(); j++){
NodeList childList = allVocs.item(j).getChildNodes();
if(vocCardList.get(i).getVocForeign().equals(childList.item(3).getTextContent())){
//int oldScore = Integer.parseInt(childList.item(5).getTextContent());
childList.item(5).setTextContent(String.valueOf(vocCardList.get(i).getErrorLevel()));
counter = allVocs.getLength();
}
}
}
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(currentVocList_path));
transformer.transform(source, result);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
private void applyStringsToCard() {
VocCard zeroCard = vocCardList.get(0);
VocCard card = vocCardList.get(zeroCard.getCount());
String foreignVoc = card.getVocForeign();
String nativeVoc = card.getVocNative();
//Make a TextView display the transfered String
TextView textViewFront = findViewById(R.id.word_foreign);
textViewFront.setText(foreignVoc);
TextView textViewBack = findViewById(R.id.word_native);
textViewBack.setText(nativeVoc);
//Adapt text size to display
DisplayMetrics metrics;
metrics = getApplicationContext().getResources().getDisplayMetrics();
float Textsize = textViewBack.getTextSize()/metrics.density;
textViewBack.setTextSize(Textsize+1);
textViewFront.setTextSize(Textsize+1);
}
public void flipCard(View view) {
if(!isBackVisible) {
mCardBackLayout.setVisibility(View.VISIBLE);
}
if (!isBackRevealed) {
mSetLeftOut.setTarget(mCardFrontLayout);
mSetRightIn.setTarget(mCardBackLayout);
mSetLeftOut.start();
mSetRightIn.start();
isBackRevealed = true;
}else {
mSetRightOut.setTarget(mCardBackLayout);
mSetLeftIn.setTarget(mCardFrontLayout);
mSetRightOut.start();
mSetLeftIn.start();
isBackRevealed = false;
}
}
}
和包含的element_layout:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/practiceLayout"
tools:context=".PracticeActivity"
android:onClick="flipCard"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container_card_back">
<include layout="@layout/card_back"/>
</FrameLayout>
<FrameLayout
android:id="@+id/container_card_front"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/card_front"/>
</FrameLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="81dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:progress="20" />
<Button
android:id="@+id/button2"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:text="empty" />
<Button
android:id="@+id/button1"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:text="empty" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/correct_button"
android:text="correct"
android:layout_above="@layout/card_front"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:onClick="correctContinuePractice"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/wrong_button"
android:text="wrong"
android:layout_above="@layout/card_front"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_alignParentLeft="true"
android:onClick="wrongContinuePractice"
/>
</RelativeLayout>