命名规范要望文知义,简单明了。
命名规范定制太多,就会让人心烦,反而没人遵守了。
—《APP研发录》
先介绍两种命名规则:
- 驼峰命名法:又称小驼峰命名法。除了首个单词首字母小写除外,其余所有单词所有首字母都要大写。
- 帕斯卡命名法:又称大驼峰命名法。所有单词首字母大写。
命名规范要望文知义,简单明了。
命名规范定制太多,就会让人心烦,反而没人遵守了。
—《APP研发录》
先介绍两种命名规则:
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import cn.xiaocaimei.devicemanager.R;
import cn.xiaocaimei.devicemanager.base.BasePanel;
public class ShowImagePanel extends FrameLayout {
// 界面
private ImageView imgFace;
public ShowImagePanel(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
@Override
protected void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.panel_show_image, this, true);
// 返回按钮
ImageButton closeBtn = findViewById(R.id.closeBtn);
closeBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setVisibility(GONE);
}
});
// 背景返回
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setVisibility(GONE);
}
});
// 头像图片
imgFace = findViewById(R.id.imgFace);
}
/**
* 展示图片
*
* @param url
*/
public void showImage(String url) {
Glide.with(this).load(url).into(imgFace);
setVisibility(VISIBLE);
}
}
参考链接:
节选自:Object.requireNonNull 方法说明
首先, 从这个方法的名称可以看出, 这个方法使用的场景是, 我们使用一个对象的方法时, 正常的运行状态应该能保证这个对象的引用非空, 如果这个对象为空了, 那一定是其他某个地方出错了, 所以我们应该抛出一个异常, 我们不应该在这里处理这个非空异常.
其次, 这里涉及到一个很重要的编程思想, 就是 Fail-fast 思想, 翻译过来就是, 让错误尽可能早的出现, 不要等到我们很多工作执行到一半之后才抛出异常, 这样很可能使得一部分变量处于异常状态, 出现更多的错误. 这也是 requireNonNull 这个方法的设计思想, 让错误尽早出现. 使用这个方法, 我们明确的抛出异常, 发生错误时, 我们立刻抛出异常.
节选自:5分钟搞定PopUpWindow
弹窗有很多种实现方式,例如:
在这些方式中,我们主要讲 PopUpWindow 的使用方式,因为它能在任意位置弹出, 这是其他方式很难做到的。
从 Google 爸爸的开发文档中我们不难看出,首先它是一个 Window,弹出时位于其他控件的上层。
节选自:使用单Activity多Fragment架构的一些总结
MainFragment中,PagerAdapter的FragmentManager要使用Fragment的FragmentManager,通过getChildFragmentManager()获得,而不能使用getActivity().getSupportFragmentManager();
getChildFragmentManager()区别于getActivity().getSupportFragmentManager(),因为在Fragment中使用ViewPager显示多个Fragment,所以需要使用fragment中的FragmentManager;
如果使用getActivity().getSupportFragmentManager(),在ViewPager中的Fragment打开另一个Fragment时有两个问题:
(1)、两个Fragment的onCreateOptionsMenu都会被调用,从而导致被打开的Fragment的Toolbar菜单按钮点击事件失效,且会一起显示出来;
(2)、返回时,ViewPager中的Fragment的视图会为空,显示空白;
在“AndroidManifest.xml”加“largetHeap=true”可以增加内存的申请量
<application ..... android:label="XXXXXXXXXX" android:largeHeap="true"> ....... </application>
import android.os.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipUtil {
// 线程池
private static final ExecutorService ThreadPool = Executors.newCachedThreadPool();
/**
* 压缩文件列表到SD
*
* @param fileName 压缩文件名称
* @param pathList 要压缩的文件路径列表
* @param callback 回调
*/
public static void ZipFilesToSD(String fileName, List<String> pathList, ZipCallback callback) {
String zipFilePath = Environment.getExternalStorageDirectory() + File.separator + fileName;
ZipFiles(zipFilePath, pathList, callback);
}
/**
* 压缩文件列表
*
* @param zipFilePath 压缩文件保存路径
* @param pathList 要压缩的文件路径列表
* @param callback 回调
*/
public static void ZipFiles(final String zipFilePath, final List<String> pathList, final ZipCallback callback) {
ThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(zipFilePath));
for (String path : pathList) {
File file = new File(path);
ZipEntry zipEntry = new ZipEntry(file.getParentFile().getName() + File.separator + file.getName());
FileInputStream inputStream = new FileInputStream(file);
outZip.putNextEntry(zipEntry);
int len;
byte[] buffer = new byte[4096];
while ((len = inputStream.read(buffer)) != -1) {
outZip.write(buffer, 0, len);
}
outZip.closeEntry();
}
outZip.finish();
outZip.close();
callback.onSuccess(zipFilePath);
} catch (IOException e) {
e.printStackTrace();
callback.onFailed(e);
}
}
});
}
/**
* 回调接口
*/
public interface ZipCallback {
void onSuccess(String zipFilePath);
void onFailed(Exception e);
}
}
参考链接:
节选自:三种方法把文件读成一个字符串
//Example 1 //Read file content into string with - Files.lines(Path path, Charset cs) private static String readLineByLineJava8(String filePath) { StringBuilder contentBuilder = new StringBuilder(); try (Stream<String> stream = Files.lines( Paths.get(filePath), StandardCharsets.UTF_8)) { stream.forEach(s -> contentBuilder.append(s).append("\n")); } catch (IOException e) { e.printStackTrace(); } return contentBuilder.toString(); } //Example 2 //Read file content into string with - Files.readAllBytes(Path path) private static String readAllBytesJava7(String filePath) { String content = ""; try { content = new String ( Files.readAllBytes( Paths.get(filePath) ) ); } catch (IOException e) { e.printStackTrace(); } return content; } //Example 3 //Read file content into string with - using BufferedReader and FileReader //You can use this if you are still not using Java 8 private static String usingBufferedReader(String filePath) { StringBuilder contentBuilder = new StringBuilder(); try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String sCurrentLine; while ((sCurrentLine = br.readLine()) != null) { contentBuilder.append(sCurrentLine).append("\n"); } } catch (IOException e) { e.printStackTrace(); } return contentBuilder.toString(); }